sql >> Database >  >> NoSQL >> MongoDB

Spring Boot-integratietesten met Embedded MongoDB

1. Overzicht

In deze zelfstudie leren we hoe we de ingebouwde MongoDB-oplossing van Flapdoodle samen met Spring Boot kunnen gebruiken om MongoDB-integratietests soepel uit te voeren.

MongoDB is een populaire NoSQL-documentdatabase . Dankzij de hoge schaalbaarheid, ingebouwde sharding en uitstekende community-ondersteuning wordt het vaak beschouwd als "de NoSQL-opslag” door veel ontwikkelaars.

Zoals met elke andere persistentietechnologie, is het van cruciaal belang om de database-integratie met de rest van onze applicatie eenvoudig te kunnen testen . Gelukkig stelt Spring Boot ons in staat om dat soort tests gemakkelijk te schrijven.

2. Maven-afhankelijkheden

Laten we eerst de Maven-ouder instellen voor ons Boot-project.

Dankzij de ouder hoeven we de versie voor elke Maven-afhankelijkheid niet handmatig te definiëren .

We gaan natuurlijk Spring Boot gebruiken:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.1</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>

Je kunt de nieuwste Boot-versie hier vinden.

Sinds we Spring Boot-ouder hebben toegevoegd, kunnen we vereiste afhankelijkheden toevoegen zonder hun versies op te geven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

spring-boot-starter-data-mongodb zal Spring-ondersteuning voor MongoDB inschakelen:

<dependency>
    <groupId>de.flapdoodle.embed</groupId>
    <artifactId>de.flapdoodle.embed.mongo</artifactId>
    <scope>test</scope>
</dependency>

de.flapdoodle.embed.mongo biedt embedded MongoDB voor integratietests.

3. Test met ingesloten MongoDB

Deze sectie behandelt twee scenario's:Spring Boot-test en handmatige test.

3.1. Spring Boot Test

Na het toevoegen van de.flapdoodle.embed.mongo afhankelijkheid Spring Boot zal automatisch proberen de ingesloten MongoDB te downloaden en te starten bij het uitvoeren van tests.

Het pakket wordt voor elke versie slechts één keer gedownload, zodat volgende tests veel sneller verlopen.

In dit stadium zouden we in staat moeten zijn om de voorbeeld JUnit 5 integratietest te starten en te halen:

@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");
    }
}

Zoals we kunnen zien, is de ingebedde database automatisch gestart door Spring, die ook in de console moet worden ingelogd:

...Starting MongodbExampleApplicationTests on arroyo with PID 10413...

3.2. Handmatige configuratietest

Spring Boot start en configureert automatisch de ingesloten database en injecteert vervolgens MongoTemplate bijvoorbeeld voor ons. soms moeten we de ingebouwde Mongo-database echter handmatig configureren (bijv. bij het testen van een specifieke DB-versie).

Het volgende fragment laat zien hoe we de ingesloten MongoDB-instantie handmatig kunnen configureren. Dit is ongeveer het equivalent van de vorige voorjaarstest:

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");
    }
}

Merk op dat we snel MongoTemplate kunnen maken bean geconfigureerd om onze handmatig geconfigureerde ingesloten database te gebruiken en deze te registreren in de Spring-container door simpelweg een @TestConfiguration te maken met @Bean methode die nieuwe MongoTemplate(MongoClients.create(connectionString, "test") retourneert .

Meer voorbeelden zijn te vinden op de officiële Flapdoodle's GitHub-repository.

3.3. Loggen

We kunnen logberichten voor MongoDB configureren bij het uitvoeren van integratietests door deze twee eigenschappen toe te voegen aan src/test/resources/application.propertes bestand:

logging.level.org.springframework.boot.autoconfigure.mongo.embedded
logging.level.org.mongodb

Om bijvoorbeeld logboekregistratie uit te schakelen, stellen we de waarden eenvoudig in op uit :

logging.level.org.springframework.boot.autoconfigure.mongo.embedded=off
logging.level.org.mongodb=off

3.4. Een echte database over productie gebruiken

Sinds we de.flapdoodle.embed.mongo hebben toegevoegd afhankelijkheid met behulp van test het is niet nodig om de ingesloten database uit te schakelen wanneer deze in productie wordt uitgevoerd . Het enige wat we hoeven te doen is de MongoDB-verbindingsdetails (bijv. host en poort) specificeren en we zijn klaar om te gaan.

Om een ​​embedded DB buiten tests te gebruiken, kunnen we Spring-profielen gebruiken die de juiste MongoClient registreren (embedded of productie) afhankelijk van het actieve profiel.

We moeten ook het bereik van de productie-afhankelijkheid wijzigen in runtime .

4. Ingebedde testcontroverse

Het gebruik van een ingesloten database lijkt in het begin misschien een geweldig idee. Het is inderdaad een goede benadering wanneer we willen testen of onze applicatie zich correct gedraagt ​​op gebieden zoals:

  • Object<->Configuratie documenttoewijzing
  • Aangepaste luisteraars voor levenscyclusgebeurtenissen voor persistentie (raadpleeg AbstractMongoEventListener )
  • De logica van elke code die rechtstreeks met de persistentielaag werkt

Helaas kan het gebruik van een embedded server niet worden beschouwd als “volledige integratietest” . De ingebouwde MongoDB van Flapdoodle is geen officieel MongoDB-product. Daarom kunnen we er niet zeker van zijn dat het zich precies zo gedraagt ​​als in de productieomgeving.

Als we communicatietesten in de omgeving zo dicht mogelijk bij de productie willen uitvoeren, is een betere oplossing om een ​​omgevingscontainer zoals Docker te gebruiken.

Lees hier ons vorige artikel voor meer informatie over Docker.


  1. server heeft fout geretourneerd bij SASL-verificatiestap:verificatie mislukt

  2. Verwijder Redis op Mac OSX. Oudere versie is actief na het installeren van de update

  3. WiredTiger en interne updates

  4. Redis Sentinels met TLS