1. Panoramica
In questo tutorial impareremo come utilizzare la soluzione MongoDB incorporata di Flapdoodle insieme a Spring Boot per eseguire senza problemi i test di integrazione di MongoDB.
MongoDB è un popolare database di documenti NoSQL . Grazie all'elevata scalabilità, allo sharding integrato e all'eccellente supporto della community, è spesso considerato "il Archiviazione NoSQL” da molti sviluppatori.
Come con qualsiasi altra tecnologia di persistenza, è fondamentale poter testare facilmente l'integrazione del database con il resto della nostra applicazione . Per fortuna, Spring Boot ci consente di scrivere facilmente questo tipo di test.
2. Dipendenze Maven
Per prima cosa, impostiamo il genitore Maven per il nostro progetto Boot.
Grazie al genitore non è necessario definire manualmente la versione per ogni dipendenza Maven .
Utilizzeremo naturalmente Spring Boot:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
Puoi trovare l'ultima versione di Boot qui.
Dato che abbiamo aggiunto il genitore Spring Boot, possiamo aggiungere le dipendenze richieste senza specificarne le versioni:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
Spring-boot-starter-data-mongodb abiliterà il supporto Spring per MongoDB:
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
de.flapdoodle.embed.mongo fornisce MongoDB incorporato per i test di integrazione.
3. Prova utilizzando MongoDB incorporato
Questa sezione copre due scenari:test Spring Boot e test manuale.
3.1. Test di avvio di primavera
Dopo aver aggiunto de.flapdoodle.embed.mongo dipendenza Spring Boot proverà automaticamente a scaricare e avviare il MongoDB incorporato durante l'esecuzione dei test.
Il pacchetto verrà scaricato solo una volta per ogni versione in modo che i test successivi vengano eseguiti molto più velocemente.
A questo punto dovremmo essere in grado di avviare e superare il test di integrazione JUnit 5 di esempio:
@DataMongoTest
@ExtendWith(SpringExtension.class)
public class MongoDbSpringIntegrationTest {
@DisplayName("given object to save"
+ " when save object using MongoDB template"
+ " then object is saved")
@Test
public void test(@Autowired MongoTemplate mongoTemplate) {
// given
DBObject objectToSave = BasicDBObjectBuilder.start()
.add("key", "value")
.get();
// when
mongoTemplate.save(objectToSave, "collection");
// then
assertThat(mongoTemplate.findAll(DBObject.class, "collection")).extracting("key")
.containsOnly("value");
}
}
Come possiamo vedere, il database embedded è stato avviato automaticamente da Spring, che dovrebbe essere registrato anche nella console:
...Starting MongodbExampleApplicationTests on arroyo with PID 10413...
3.2. Test di configurazione manuale
Spring Boot avvierà e configurerà automaticamente il database incorporato, quindi inietterà MongoTemplate esempio per noi. Tuttavia, a volte potrebbe essere necessario configurare manualmente il database Mongo incorporato (ad es. durante il test di una specifica versione del DB).
Il frammento di codice seguente mostra come configurare manualmente l'istanza MongoDB incorporata. Questo è più o meno l'equivalente del precedente test di primavera:
class ManualEmbeddedMongoDbIntegrationTest {
private static final String CONNECTION_STRING = "mongodb://%s:%d";
private MongodExecutable mongodExecutable;
private MongoTemplate mongoTemplate;
@AfterEach
void clean() {
mongodExecutable.stop();
}
@BeforeEach
void setup() throws Exception {
String ip = "localhost";
int port = 27017;
ImmutableMongodConfig mongodConfig = MongodConfig
.builder()
.version(Version.Main.PRODUCTION)
.net(new Net(ip, port, Network.localhostIsIPv6()))
.build();
MongodStarter starter = MongodStarter.getDefaultInstance();
mongodExecutable = starter.prepare(mongodConfig);
mongodExecutable.start();
mongoTemplate = new MongoTemplate(MongoClients.create(String.format(CONNECTION_STRING, ip, port)), "test");
}
@DisplayName("given object to save"
+ " when save object using MongoDB template"
+ " then object is saved")
@Test
void test() throws Exception {
// given
DBObject objectToSave = BasicDBObjectBuilder.start()
.add("key", "value")
.get();
// when
mongoTemplate.save(objectToSave, "collection");
// then
assertThat(mongoTemplate.findAll(DBObject.class, "collection")).extracting("key")
.containsOnly("value");
}
}
Tieni presente che possiamo creare rapidamente MongoTemplate bean configurato per utilizzare il nostro database incorporato configurato manualmente e registrarlo all'interno del contenitore Spring semplicemente creando, ad esempio, un @TestConfiguration con @Bean metodo che restituirà new MongoTemplate(MongoClients.create(connectionString, “test”) .
Altri esempi possono essere trovati sul repository GitHub ufficiale di Flapdoodle.
3.3. Registrazione
Possiamo configurare i messaggi di registrazione per MongoDB durante l'esecuzione dei test di integrazione aggiungendo queste due proprietà a src/test/resources/application.propertes file:
logging.level.org.springframework.boot.autoconfigure.mongo.embedded
logging.level.org.mongodb
Ad esempio, per disabilitare la registrazione, impostiamo semplicemente i valori su off :
logging.level.org.springframework.boot.autoconfigure.mongo.embedded=off
logging.level.org.mongodb=off
3.4. Utilizzo di un vero database in produzione
Da quando abbiamo aggiunto de.flapdoodle.embed.mongo dipendenza usando
Per utilizzare un DB incorporato al di fuori dei test, possiamo utilizzare profili Spring che registreranno il MongoClient corretto (embedded o di produzione) a seconda del profilo attivo.
Dovremo anche modificare l'ambito della dipendenza di produzione in
4. Polemica sui test incorporati
L'uso del database incorporato potrebbe sembrare un'ottima idea all'inizio. In effetti, è un buon approccio quando vogliamo testare se la nostra applicazione si comporta correttamente in aree come:
- Oggetto<->Configurazione mappatura documenti
- Listener di eventi del ciclo di vita della persistenza personalizzati (fare riferimento a AbstractMongoEventListener )
- La logica di qualsiasi codice che lavora direttamente con il livello di persistenza
Sfortunatamente, l'utilizzo di un server incorporato non può essere considerato un "test di integrazione completo" . MongoDB incorporato di Flapdoodle non è un prodotto MongoDB ufficiale. Pertanto, non possiamo essere sicuri che si comporti esattamente come nell'ambiente di produzione.
Se vogliamo eseguire test di comunicazione nell'ambiente il più vicino possibile alla produzione, una soluzione migliore è utilizzare un container dell'ambiente come Docker.
Per saperne di più su Docker, leggi il nostro precedente articolo qui.