# Objeto mock

Objetos mock, objetos simulados ou simplesmente mock (do inglês mock object) em desenvolvimento de software são objetos que simulam o comportamento de objetos reais de forma controlada. São normalmente criados para testar o comportamento de outros objetos. Em outras palavras, os objetos mock são objetos “falsos” que simulam o comportamento de uma classe ou objeto “real” para que possamos focar o teste na unidade a ser testada.

## Razões para usar

Em teste unitário, pode simular o comportamento de objetos reais complexos e são, portanto, muito úteis quando os objetos reais são difíceis de criar ou impossíveis de serem incorporados no teste de unidade. Por exemplo, em um teste para um objeto que faz uma chamada remota é necessário que do outro lado exista um previsão para a chamada. Neste caso, em vez de usar o objeto real que faz a chamada, usa-se um mock object que simula o comportamento do objeto real. Se um objeto tem alguma das características a seguir, é provável que mock objects possam ser utilizados em seu lugar:
* gera resultados não determinísticos (e.g. a hora ou temperatura atual);
* tem estados que são difíceis de criar ou reproduzir (e.g. erro de comunicação da rede);
* é lento (e.g. um banco de dados completo que precisa ser inicializado antes do teste);
* ainda não existe ou pode ter comportamento alterado;
* teriam que adicionar informações e métodos exclusivamente para os testes (e não para sua função real).
Por exemplo, um programa de despertador que faz uma campainha tocar em um certo momento necessita obter a hora atual. Para testar este comportamento, o teste de unidade deve esperar até que a hora programada chegue, para testar a campainha de forma correta. Se um mock object for usado no lugar do objeto real, então ele pode ser programada para simular a hora de programação do despertador. Assim o código do despertador pode ser testado corretamente.

## Exemplo

Suponha que um banco de dados de produção precisa ser testado, este SGBD já tem uma boa quantia de registros e uma busca no mesmo é lenta.
para tal teste, é criado uma classe MockOrderRepositoryService que simula o serviço do banco e uma classe, OrderRepository, que é responsável pela injeção de dependência:
Código em C#
Classe que simula o SGBD
A seguinte utilização de testes unitários sobre o serviço do banco não irá utilizar o banco de dados de produção (lento), mas sim o serviço simulado:
Código em C#

## Limitações

O uso de objetos mock pode casar os testes unitários com a atual implementação do código que está sendo testado. Por exemplo, alguns frameworks de objetos mock permitem ao desenvolvedor especificar a ordem e o número de vezes que os métodos num objeto mock são chamados; um sucessivo refactoring do código que está sendo testado, poderia portanto fazer que o teste falhe, mesmo se o método ainda obedece a lógica da implementação anterior.
Isso nega completamente um dos benefícios oferecidos pelos testes unitários. Excesso de uso de objetos mock como parte de uma suíte de testes unitários poderia então resultar num crescimento dramático de modificações que precisam ser feitas nos testes durante a evolução do sistema quando o refactoring é feito. Manutenção incorreta durante a evolução destes testes pode fazer com que certos erros passem despercebidos. Tais erros podem ser notados por testes unitários que usam instâncias de classes reais, os quais não precisam ser feitos frequentemente.
Um objeto mock tem precisamente o modelo do comportamento do objeto que ele está simulando ("mocking"). O comportamento correto pode se tornar difícil de se obter se o objeto que está sendo simulado ("mocked") foi feito por outro desenvolvedor, ou, quando esse não tenha sido escrito ainda. Se o comportamento não for modelado corretamente, então os testes unitários devem registrar que o teste passou mesmo se uma falha ocorresse no tempo de execução, nas mesmas condições que o teste está exercendo e dessa forma, tornando inútil o teste unitário.