Testes de integração com mongoDB (.NET)

Felipe Almeida
Tradeback
Published in
5 min readMar 25, 2021
Fonte: https://www.flickr.com/photos/sukiweb/10223596316

Testes automatizados não é um assunto exatamente novo, porém ainda hoje, são negligenciados por muitas empresas, contando com a vista grossa dos desenvolvedores.

Muitas vezes os testes automatizados são ignorados por falta de cultura ou até mesmo por falta de conhecimento técnico para desenvolve-los, principalmente no caso dos testes de integração com o banco de dados, que envolvem a necessidade de uma infraestrutura de banco para que os testes sejam executados.

Tendo isso em vista, o objetivo desta publicação é incentivar o desenvolvimento de testes automatizados que envolvem o banco de dados mongoDB, divulgando o pacote Mongo2Go, disponível via NuGet, que nos ajudará com todo o trabalho relativo à infraestrutura dos testes.

Pirâmide de testes

Primeiramente, é importante lembrar da pirâmide de testes e saber escolher corretamente o tipo de teste que você irá aplicar em cada cenário da sua aplicação. Na maioria dos casos, um teste de unidade, muito mais simples e leve, irá atender sua necessidade.

Então, onde o teste de integração envolvendo o banco de dados pode ser importante? A resposta é: em cenários onde você precisa testar uma consulta no banco, um relatório, etc.

Por exemplo, suponhamos que em um aplicativo de controle de gastos, precisemos consultar os gastos de um usuário de acordo com um período informado. Uma possibilidade de teste seria garantir que gastos fora do período informado não sejam retornados.

Abaixo, irei demonstrar os passos gerais para a configuração dos testes integrados e na sequência mostrar um teste para cobrir o cenário acima descrito.

Setup dos testes integrados com mongoDB

Uma vez que seu projeto de testes foi criado (para este exemplo, estamos utilizando o MSTest, mas fica à sua preferência utilizar qualquer framework de testes), precisamos adicionar o pacote Mongo2Go.

O pacote Mongo2Go trás consigo os executáveis necessários para rodar uma instância local do mongoDB. Por trás dos panos, o que acontecerá é que antes da execução de cada teste, iremos rodar uma nova instância de um servidor mongoDB e ao final de cada teste, iremos derrubar esta instância.

Com isso dito, você ja deve imaginar que o tempo de execução dos testes integrados não é tão rápido quanto um teste simples de unidade, portanto, escolha muito bem o momento de utilizar esta estrutura de testes. O tempo da execução de cada teste varia de máquina para máquina e também de acordo com o teste que está sendo executado, porém um teste simples na minha máquina leva cerca de 2 segundos para ser executado.

Para não repetir o código referente ao setup do mongoDB para os testes, eu costumo utilizar uma classe MongoDBInfraBaseTests que é herdade por todas as classes de teste de integração:

Como podem ver, o setup é muito simples. O simples comando MongoDbRunner.Start(), é responsável por subir uma instância do mongoDB em uma porta livre da sua máquina e através da propriedade _runner.ConnectionString, podemos pegar a ConnectionString necessária para criar nossa conexão com o mongoDB.

Também é muito importante reparar no TestCleanup, contendo o comando _runner.Dispose(), responsável por “matar” a instancia do mongoDB criada para o teste.

Outra dica importante é que quando estivermos debugando um teste de integração, nunca devemos interromper a execução do teste, pois do contrário, o [TestCleanup] não será executado e o processo do mongoDB irá rodar na sua máquina até que você “mate” ele manualmente ou reinicie sua máquina.

Aplicação: Controle de Gastos

Para criarmos os testes integrados, iremos utilizar o exemplo da aplicação de Controle de Gastos, que terá apenas um método no repositório, responsável por listar os gastos de um participante, filtrando por um período.

Testes de integração com o mongoDB

Finalmente chegamos ao momento mais esperado: ver a implementação de fato dos testes de integração.

Criei então uma classe de teste para o nosso repositório que nomeei de TestesRepositórioGasto herdando nossa classe MongoDBInfraBaseTests e criei um método [TestInitialize] para criar a instância do nosso repositório:

Por fim, criei um método de teste que valida que apenas os gastos realizados dentro do intervalo informado estão sendo retornados.

Para isso, foi preciso criar uma pequena massa de dados, contendo os gastos hipotéticos do nosso usuário, e portanto, utilizamos a MongoCollection de Gastos “collectionGastos”, criada pelo MongoDBInfraBaseTests, conforme podemos observar:

Criamos então gastos de 20 dias no passado, até “hoje” e na consulta realizada no repositório, passamos um período de 10 dias atrás até 5 dias atrás. Desta forma, os gastos de 20 dias atrás e o gasto de “hoje” não devem ser retornados.

Por fim, foi validado que apenas 2 gastos foram retornados e que estes, eram os gastos esperados.

O código utilizado para estes testes está disponível no repositório do GitHub.

Espero que esta publicação tenha ajudado a desmistificar a complexidade de um teste de integração e que sirva de incentivo para que uma cultura de testes mais ampla seja adotada.

Caso reste alguma dúvida, não hesite em entrar em contato.

Se gostou desta publicação, não esqueça de bater palmas 👏👏👏

--

--

Felipe Almeida
Tradeback

Desenvolvedor, amante de bike, trilhas e campings