Teste de integração de inicialização com o MongoDB incorporado

Teste de integração de inicialização com o MongoDB incorporado

1. Visão geral

Neste tutorial, aprenderemos como usar a solução MongoDB embutida do Flapdoodle junto com Spring Boot para executar testes de integração MongoDB sem problemas.

MongoDB is a popular NoSQL document database. Graças à alta escalabilidade, fragmentação integrada e excelente suporte da comunidade, é frequentemente considerado "the armazenamento NoSQL" por muitos desenvolvedores.

Como com qualquer outra tecnologia de persistência,it’s critical to be able to test database integration with the rest of our application easily. Felizmente, o Spring Boot nos permite escrever esse tipo de teste facilmente.

2. Dependências do Maven

Primeiro, vamos configurar o pai Maven para nosso projeto de inicialização.

Graças ao paiwe don’t need to define version for each Maven dependency manually.

Naturalmente, usaremos o Spring Boot:


    org.springframework.boot
    spring-boot-starter-parent
    2.0.3.RELEASE
     

Você pode encontrar a versão mais recente do Boothere.

Desde que adicionamos o pai do Spring Boot, podemos adicionar as dependências necessárias sem especificar suas versões:


    org.springframework.boot
    spring-boot-starter-data-mongodb

spring-boot-starter-data-mongodb habilitará o suporte Spring para MongoDB:


    de.flapdoodle.embed
    de.flapdoodle.embed.mongo
    test

de.flapdoodle.embed.mongo fornece MongoDB integrado para testes de integração.

3. Teste usando MongoDB integrado

Esta seção abrange dois cenários: teste de inicialização da primavera e teste manual.

3.1. Spring Boot Test

Depois de adicionarde.flapdoodle.embed.mongo dependênciaSpring Boot will automatically try to download and start the embedded MongoDB ao executar testes.

O pacote será baixado apenas uma vez para cada versão, para que os testes subsequentes sejam executados muito mais rapidamente.

Nesta fase, devemos poder iniciar e passar no teste de integração de amostra do JUnit 5:

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

Como podemos ver, o banco de dados incorporado foi iniciado automaticamente pelo Spring, que também deve ser registrado no console:

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

3.2. Teste de configuração manual

O Spring Boot irá iniciar e configurar automaticamente o banco de dados embutido e então injetarMongoTemplate instância para nós. No entanto,sometimes we might need to configure embedded Mongo database manually (por exemplo, ao testar uma versão de banco de dados específica).

O seguinte trecho mostra como podemos configurar a instância incorporada do MongoDB manualmente. Isso é aproximadamente o equivalente ao teste anterior da primavera:

class ManualEmbeddedMongoDbIntegrationTest {
    private MongodExecutable mongodExecutable;
    private MongoTemplate mongoTemplate;

    @AfterEach
    void clean() {
        mongodExecutable.stop();
    }

    @BeforeEach
    void setup() throws Exception {
        String ip = "localhost";
        int port = 27017;

        IMongodConfig mongodConfig = new MongodConfigBuilder().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(new MongoClient(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");
    }
}

Observe que podemos criar rapidamente o beanMongoTemplate configurado para usar nosso banco de dados embutido configurado manualmente e registrá-lo dentro do container Spring meramente criando, por exemplo, um método@TestConfiguration com@Bean que retornará new MongoTemplate(new MongoClient(bindIp, port), “test”).

Mais exemplos podem ser encontrados noGitHub repository oficial do Flapdoodle.

3.3. Exploração madeireira

Podemos configurar mensagens de registro para MongoDB ao executar testes de integração, adicionando essas duas propriedades ao arquivosrc/test/resources/application.propertes:

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

Por exemplo, para desativar o registro, simplesmente definimos os valores paraoff:

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

3.4. Usando um banco de dados real na produção

Uma vez que adicionamosde.flapdoodle.embed.mongo dependência usando<scope>test</scope>there’s no need to disable embedded database when running on production. Tudo o que precisamos fazer é especificar os detalhes da conexão do MongoDB (por exemplo, host e porta) e estamos prontos.

Para usar um banco de dados embutido fora dos testes, podemos usar perfis Spring que registrarão osMongoClient corretos (embutidos ou de produção) dependendo do perfil ativo.

Também precisaremos alterar o escopo da dependência de produção para<scope>runtime</scope>.

4. Controvérsia de testes incorporados

Usar banco de dados incorporado pode parecer uma ótima idéia no começo. Na verdade, é uma boa abordagem quando queremos testar se nosso aplicativo se comporta corretamente em áreas como:

  • Objeto <→ Configuração de mapeamento de documento

  • Ouvintes de evento de ciclo de vida de persistência customizada (consulteAbstractMongoEventListener)

  • A lógica de qualquer código que trabalha diretamente com a camada de persistência

Infelizmente,using an embedded server cannot be considered as “full integration testing”. O MongoDB incorporado do Flapdoodle não é um produto oficial do MongoDB. Portanto, não podemos ter certeza de que ele se comporta exatamente como no ambiente de produção.

Se quisermos executar testes de comunicação no ambiente o mais próximo possível da produção, uma solução melhor é usar um contêiner de ambiente como o Docker.

Para saber mais sobre o Docker, leia nosso artigo anteriorhere.

5. Conclusão

O Spring Boot torna extremamente simples a execução de testes que verificam o mapeamento adequado de documentos e a integração com o banco de dados. Ao adicionar a dependência correta do Maven, podemos usar imediatamente os componentes do MongoDB nos testes de integração do Spring Boot.

Precisamos lembrar queembedded MongoDB server cannot be considered a replacement for a “real” server.

O código-fonte completo de todos os exemplos está disponívelover on GitHub.