Escrevendo testes unitários para seus repositórios MongoDB usando o FlapDoodle Embedded MongoDB

Sidharta Rezende
3 min readAug 1, 2020

Um aspecto do desenvolvimento de software que vem me interessando cada vez mais é qualidade. Posso afirmar com certeza que após começar a praticar ativamente TDD (Test driven development) a qualidade do meu código e das minhas entregas aumentou de forma exponencial. Mais que isso, praticar TDD plantou a semente da preocupação contínua com qualidade.

Pretendo abordar em uma séria de artigos algumas das práticas que me ajudam a conseguir aplicar o TDD de forma efetiva e que moldaram minha abordagem sobre qualidade no desenvolvimento de software.

Para começar, escolhi um assunto que tem um certo potencial de polêmica: Testes unitários de repositórios usando uma instancia embedded do banco.
Polêmico por 2 motivos:

  • Pode ser questionável a necessidade de testar a camada repositório (e, em nível mais essencial, até mesmo a necessidade de efetivamente escrever o código nessa camada)
  • Partindo do pressuposto que você vê valor no item anterior, uma abordagem alternativa — e muito difundida — é subir uma instância do banco no docker, criar um database com sufixo "-test" e executar seus testes nesse Database.

Pessoalmente, sou super fã de docker e de "conteinerização", mas vejo duas vantagens matadoras em usar a abordagem "embedded":

1 -Independência dos container — não sabemos com certeza as características do ambiente que os desenvolvedores contarão. Questões como diferentes privilégios de acesso e até mesmo impossibilidade total de levantar containers devem ser levadas em conta

2 -É mais rápido e mais fácil levantar uma instância embedded do que dropar database a cada execução de testes.

Um ponto de resistência de muitos desenvolvedores em aplicar o TDD é a divisão de foco entre o teste e o código de produção. Quanto mais tempo entre as interações, mais essa sensação de perda de foco é maximizada. Acredito que a decisão de qual estratégia adotar para os testes deve ter como preocupação fundamental fornecer a melhor experiência possível para o desenvolvedor.

Para o restante desse artigo, mostrarei uma abordagem para testar repositórios MongoDB utilizando o projeto Flapdoodle.

Usarei Kotlin como linguagem nos exemplos e no projeto que disponibilizo de modelo https://github.com/the-sidh/zmovies

O MongoDB é o banco que eu mais tenho usado, tanto em projetos pessoais quanto profissionalmente. Ele é amplamente usado no mercado, e por isso acredito ser relevante para essa abordagem.

Flapdoodle Embedded MongoDB

O Flapdoodle (https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo) é um projeto open source que tem como objetivo prover uma plataforma para neutra para rodar testes unitários no MongoDB.
Basicamente, precisamos subir um um processo do MongoDB.

fun start(val host: String, val port: Int) {
val starter = MongodStarter.getDefaultInstance()
val mongodConfig = MongodConfigBuilder()
.version(Version.Main.V4_0)
.net(Net(host, port, Network.localhostIsIPv6()))
.build()
val mongodExecutable: MongodExecutable = starter.prepare(mongodConfig)
val mongodProcess: MongodProcess = mongodExecutable.start()
}

Feito isso, temos nosso processo do MongoDB rodando.

No projeto de exemplo, isolei esses objetos em uma classe holder, para poder fazer referencia a ela por dentro de uma classe extension do JUnit5

override fun beforeAll(context: ExtensionContext?) {
flapDoodleHolder.start()
}

override fun afterAll(context: ExtensionContext?) {
flapDoodleHolder.stop()
}

override fun beforeEach(context: ExtensionContext?) {
flapDoodleHolder.clean()
}
}

O código de referência pode ser encontrado aqui:

https://github.com/the-sidh/zmovies/blob/master/src/test/kotlin/com/thesidh/zmovie/storage/holder/FlapDoodleHolder.kt
E aqui:
https://github.com/the-sidh/zmovies/blob/master/src/test/kotlin/com/thesidh/zmovie/storage/extension/MongoDBExtension.kt

Uma vez feito isso, consigo utilizar toda essa instância embedded para executar meus testes. Na classe de teste, basta fazer referência à extension:

@ExtendWith(MongoDBExtension::class)
class MongoDBMoviesRepositoryTest(private val mongoDatabase: MongoDatabase) {
(...)}

E a partir daí, é só felicidade!

Happy TDD!

--

--

Sidharta Rezende

Skatista de downhill, amante da vida e Engenheiro de Software