Quando Usar Objetos Mocks?

Precisei fazer alguns objetos mocks no trabalho e achei um artigo interessante sobre uso de frameworks de Objetos Mock. Segue o artigo do K Scott Allen:

 

Mocks – Esta é uma Questão de Quando.

Ross Neilson lembrou-me uma pergunta que me deixou enforcado: “Quando eu uso um Mock Framework?”

 

Se você perguntar “quando”, a resposta é provavelmente “não agora”. Eu sinto que framework de objetos de mentira (Mock Objects) é algo que você tem que evoluir.

Primeiro, nós podemos falar sobre Mocks em geral. Algumas pessoas tem a concepção que Objetos Mock são apenas útil se você precisa simular uma iteração com um recurso que é difícil usar em testes de unidade – como um objeto que comunica com um servidor SMTP. Isso não é verdade. Colin Mackay tem um artigo sobre mocks que demonstra outros cenários comuns.

 

  • O objeto real tem comportamento não determinístico
  • O objeto real é difícil de configurar
  • O objeto real tem comportamento que é difícil de acionar
  • O objeto real é lento
  • O objeto real é uma interface de usuário
  • O objeto real usa uma chamada de retorno (call back)
  • O objeto real ainda não existe

 

Se dermos um passo para trás e generalizarmos essa lista, diríamos que test doubles são úteis quando você quer isolar um código do seu teste. Digamos que estamos escrevendo testes para um componente de negócio. Nós não gostaríamos que o teste falhe quando alguém introduzir um código ruim de um serviço de auditoria usado pelo componente de negócio. Nós somente queremos testar a falha quando alguma coisa está errada com o próprio componente de negócio. Fornecer um mock para o serviço de auditoria nos permite isolar o componente de negócio e controlar qualquer estímulo que o componente pode receber desse serviço de auditoria. Quando você começar a sentir a dor de escrever vários test doubles na mão, você vai saber que necessita de um framework de Objetos Mock.

 

Mocks não são somente sobre isolamento, no entanto. Mocks tem também um papel no desenvolvimento orientado a testes (TDD), o qual se refere Colin no último ítem. O autor de Mock Roles, Not Objects” diz que mocks são:

“Uma tecnica para identificar tipos baseado em papéis que o objeto desempenha em um sistema… Em particular, nós agora sabemos que o maior benefício de Objetos Mock é aquilo que originalmente chamamos de descoberta de interfaces”

 

Usar um framework de Objetos Mock no TDD permite um contínuo, top-down desing de software. Muitos fãs de TDD sabem que necessitam de um framework de Objetos Mock um dia.

 

Mas frameworks de Objetos Mocks não são complexos?

 

 Essa é outra questão que eu fui questionado recentemente. Frameworks de Objetos Mocks são atualmente mais simples e expõem uma pequena API. Existe complexidade, porém, não no framework em si. Como eu disse anteriormente, eu penso que existe um caminho que você segue para evoluir no uso de frameworks de Objetos Mock. Um típico time de um projeto usando framework de Objetos Mock tem vivência com TDD e Containers de Inversão de Controle. Tentar ter velocidade com todos esses tópicos de uma vez pode ser esmagador. 

 

Existe também alguma complexidade no uso de mocks efetivamente. Em Mocks and the Dangers of Overspecified Software, Ian Cooper diz:

 

“Quando você muda a implementação de um método através de um teste, mocks podem quebrar porque você pode fazer chamadas adicionais ou diferentes para o componente dependente que está sendo mocado.  …  O mock começou a fazer nosso software mais resistente a mudança, mais lento, e isso aumentou o custo para refactoring. Como a mudança se tornou mais caro, nós ficávamos resistentes a fazer isso, e corremos o risco de começar a construir débitos técnicos (technical debt). As vezes um teste quebra, quando desenvolvedores mudam o domínio, ou mudou o modo de como fomos fazer a persistência, sem alterar o teste em primeiro lugar, porque eles ficaram frustados de como isso deixou mais lento o seu desenvolvimento. Os mocks se tornaram um impedimento ao progresso.”

 

Framworks de Objetos Mocks fazem fáceis interações baseada em testes, mas podem também levar a problemas que o Ian Cooper descreve acima. Aqui está mais algumas leituras para esse tópico:

 

Guidelines to Using Interaction Based Testing

Why Mock Frameworks Suck

 

Em resumo, frameworks de Objetos Mocks (por exemplo JMock, EasyMock, and NUnit) não são para tudo, Você deverá saber quando  necessitar de um.

3 Respostas to “Quando Usar Objetos Mocks?”

  1. TDD é realmente necessário? « Manifesto na Web! Says:

    […] posts sobre esse assunto, quem quiser pode dar uma lida e fiquem a vontade em comentar aqui e aqui Postado em Test Driven Development, […]

  2. Marcos Urata Says:

    Belo artigo.

    Mas me diga uma coisa. Baseado na sua experiência, vc recomendaria o uso de mock objects na camada de negócio/domínio quando alguns métodos de negócio dessa camada precisarem acessar recursos como DAOs/Repositorios?

    Ainda nao consegui ver uma real vantagem de eu criar/popular um mock object que eh manipulado por um método de negocio, em vez de retornar o proprio objeto persistente para esse método.

    O ponto contra que eu vejo é que há uma dependência de uma integração com o BD para os testes funcionarem. Por outro lado, eu evito um pouco o “technical debt” por não dispender muito esforço implementando mock objects.

    Atualmente eu implemento testes unitarios (de integracao, na verdade) na camada de persistência e testes unitários na camada de negócios.

    Se os testes da camada de persistência passarem e ocorrer um erro em algum método na camada de negócios que eventualmente chama algum método persistente, é possível isolar o erro e deduzir que o problema está com a lógica de negócio em si.

    Enfim, gostaria de ouvir sua opinião a respeito.

    Abracos
    Marcos Urata

  3. Ricardo Almeida Says:

    Oi Marcos,

    Muito boa a pergunta!

    As vantagens de você usar mocks ao invés de objetos reais é que a medida que for crescendo sua cobertura de testes, a sua suite de testes tende a ficar muito lenta, principalmente se grande parte dos testes fizerem acesso ao banco. Isso prejudica seu processo de Integração Contínua. A ideia é que a suite de testes seja executada rapidamente para que você possa fazer quantas Integrações forem necessárias durante o dia.

    Outro ponto interessante é que quando você está escrevendo um teste unitário, você não quer se preocupar em como outros métodos estão se comportando, e sim se esse método do seu teste está funcionando. Com mocks você configura o valor de retorno das classes ou métodos que seu teste unitário espera/depende. O Objetivo de testes de unidade é testar somente a unidade, no caso, o método.

    Os testes que você costuma fazer, testes de integração, também são muito importantes. E tem ferramentas que auxiliam nosso trabalho, por exemplo o Selenium.

    Eu recomendo que você faça seus testes sem se preocupar com mocks. A medida que você sentir a necessidade aí sim baixe a biblioteca de sua preferência.

    A minha necessidade surgiu quando eu queria rodar meus testes offline, sem me preocupar em subir o servidor. Então eu mockei classes que faziam a conexão do banco e configurei para que me retornasse um valor esperado para meu teste. Depois mockei classes de negócio que tinham uma complexidade desnecessária para ser executado dentro do meu teste.

    Portanto, já respondendo sua pergunda, eu recomendo que crie mocks para suas classes de negócio. Por isso, se você trabalha com java, é importante que você crie interfaces para suas classes de negócio. Se você não quiser criar interfaces, dependendo da biblioteca, você pode fazer uma configuração e mocar sua própria classe.

    Você pode mocar classes de negócio, DAO’s ou Repositórios da maneira que precisar, dentro dos seu testes de unidade (NUnit, JUnit, Test::Unit, etc)

    Você não precisa popular um mock, pois a ferramenta já faz isso pra você. Você configura o retorno baseado em algumas restrições que você definir. Veja uns exemplos dessas restrições na documentação da biblioteca de mock.


Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: