Mocks são objetos que simulam o comportamento de outros objetos (como se fossem dublês).
Finalidade
Mocks são geralmente utilizados em testes unitários.
Conforme meu post sobre conceito de teste unitário, um teste unitário é um código que testa UMA unidade de código, ou seja, se estou testando uma única unidade de código, eu não quero que meu código teste uma outra unidade de código que não seja a que eu estou querendo.
Vamos imaginar a situação mais comum, no qual temos uma camada Business e esta camada realiza chamadas para a camada de DAL (Data Access Layer).
Se meus testes estão cobrindo somente os códigos da minha camada de negôcio, então teoricamente eu não deveria deixar a camada Business chamar a camada DAL, pois neste caso eu estaria testando também o código contido nesta camada. Eu quero somente testar a regra de negôcio contida na camada Business. Quero garantir que meus testes cubram somente as regras de negôcio ali desenvolvidas e não o acesso a base de dados.
Com a ajuda do Mock, podemos "mockar" a camada DAL para que ela simule o comportamento desta camada. Com isso, meu teste unitário somente testará a regra de negôcio contida na camada Business, e utilizará o Mock para as chamadas feitas a camada DAL a partir da Business.
Porque utilizá-los?
Facilidade de testar métodos que dependem de WebServices (serviços externos em geral) / Banco de Dados / Envio de Email / etc.
Utilização
Ao utilizar Mocks, é necessário entender um pouco sobre o conceito de Injeção de Dependência, no qual, será muito utilizado na implementação.
De acordo com o Wikipedia, injeção de dependência é um padrão de desenvolvimento utilizado quando é necessário manter baixo o nível de acoplamento entre diferentes módulos de um sistema.
Exemplo em C#
No exemplo abaixo utilizo o assembly do Moq, disponível no endereço: http://code.google.com/p/moq
//Interface
public interface IPessoaDAL
{
bool Incluir(PessoaEntity pessoa);
}//Classe de Negôcio
public class PessoaBusiness
{
private IPessoaDAL _pessoaDAL = null;
public PessoaBusiness(IPessoaDAL pessoaDAL)
{
_pessoaDAL = pessoaDAL;
}
public bool Incluir(PessoaEntity pessoa)
{
if (pessoa.Nome.Trim().Length == 0)
{
throw (new Exception("O nome deve ser preenchido!"));
}
if (pessoa.Idade <= 0)
{
throw (new Exception("A idade deve ser maior que zero!"));
}
return _pessoaDAL.Incluir(pessoa);
}
}
//Teste Unitário (MSTest e Moq)
[TestMethod]
public void IncluirPessoaComNomeEIdadeTest()
{
PessoaEntity pessoa = new PessoaEntity();
pessoa.Nome = "Jose";
pessoa.Idade = 88;
var mock = new Moq.Mock();
mock.Setup(x => x.Incluir(pessoa)).Returns(true);
PessoaBusiness pessoaBusiness = new PessoaBusiness(mock.Object);
bool pessoaIncluida = pessoaBusiness.Incluir(pessoa);
Assert.IsTrue(pessoaIncluida);
}
Lecal cara, estou desenvolvendo um trabalho sobre automação de testes unitários de caixa branca e com certeza os mocks são fundamentais para o processo. É importante divulgar esta tecnologia pois geralmente testes unitários geram uma certa "alergia" nso desenvolvedores, devido as complexidades de cenario.
ResponderExcluirparabens e abraços!