MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Teste de integração do Spring Boot com o MongoDB incorporado

1. Visão geral


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

MongoDB é um banco de dados de documentos NoSQL popular . Graças à alta escalabilidade, fragmentação integrada e excelente suporte da comunidade, muitas vezes é considerado “o Armazenamento NoSQL” por muitos desenvolvedores.

Como acontece com qualquer outra tecnologia de persistência, é fundamental poder testar facilmente a integração do banco de dados com o restante de nosso aplicativo . 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 Boot.

Graças ao pai não precisamos definir a versão para cada dependência do Maven manualmente .

Naturalmente, usaremos o 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>

Você pode encontrar a versão de inicialização mais recente aqui.

Como adicionamos o pai do Spring Boot, podemos adicionar as dependências necessárias sem especificar suas versões:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

spring-boot-starter-data-mongodb habilitará o suporte Spring para MongoDB:
<dependency>
    <groupId>de.flapdoodle.embed</groupId>
    <artifactId>de.flapdoodle.embed.mongo</artifactId>
    <scope>test</scope>
</dependency>

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

3. Teste usando o MongoDB incorporado


Esta seção abrange dois cenários:teste Spring Boot e teste manual.

3.1. Teste de inicialização do Spring


Depois de adicionar de.flapdoodle.embed.mongo dependência O Spring Boot tentará baixar e iniciar automaticamente o MongoDB incorporado 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 ser capazes de iniciar e passar no teste de integração de amostra 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 embutido foi iniciado automaticamente pelo Spring, que também deve ser logado no console:
...Starting MongodbExampleApplicationTests on arroyo with PID 10413...

3.2. Teste de configuração manual


O Spring Boot iniciará e configurará automaticamente o banco de dados incorporado e, em seguida, injetará MongoTemplate instância para nós. No entanto, às vezes podemos precisar configurar o banco de dados Mongo incorporado manualmente (por exemplo, ao testar uma versão específica do banco de dados).

O snippet a seguir mostra como podemos configurar manualmente a instância incorporada do MongoDB. Isso é aproximadamente o equivalente ao teste Spring anterior:
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");
    }
}

Observe que podemos criar rapidamente MongoTemplate bean configurado para usar nosso banco de dados embutido configurado manualmente e registrá-lo dentro do contêiner Spring simplesmente criando, por exemplo, um @TestConfiguration com @Bean método que retornará new MongoTemplate(MongoClients.create(connectionString, “test”) .

Mais exemplos podem ser encontrados no repositório GitHub oficial do Flapdoodle.

3.3. Registro


Podemos configurar mensagens de log para o MongoDB ao executar testes de integração adicionando essas duas propriedades a src/test/resources/application.propertes Arquivo:
logging.level.org.springframework.boot.autoconfigure.mongo.embedded
logging.level.org.mongodb

Por exemplo, para desabilitar o registro, simplesmente definimos os valores como off :
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


Como adicionamos de.flapdoodle.embed.mongo dependência usando test não há necessidade de desabilitar o banco de dados incorporado ao executar em produção . 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 incorporado fora dos testes, podemos usar perfis Spring que registrarão o MongoClient correto (incorporado ou de produção) dependendo do perfil ativo.

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

4. Controvérsia de teste incorporado


Usar o banco de dados incorporado pode parecer uma ótima ideia no começo. De fato, é uma boa abordagem quando queremos testar se nosso aplicativo se comporta corretamente em áreas como:
  • Objeto<->Configuração de mapeamento de documentos
  • Listeners de eventos de ciclo de vida de persistência personalizados (consulte AbstractMongoEventListener )
  • A lógica de qualquer código trabalhando diretamente com a camada de persistência

Infelizmente, usar um servidor incorporado não pode ser considerado um "teste de integração completo" . O MongoDB embutido 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 anterior aqui.