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

thesidh

the-sidh

Posted on August 1, 2020

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

Alt Text

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) é 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:

FlapDoodleHolder.kt

E aqui:

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!

💖 💪 🙅 🚩
thesidh
the-sidh

Posted on August 1, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related