Como zombar corretamente e teste de unidade
Estou basicamente tentando me ensinar a codificar e quero seguir boas práticas. Existem benefícios óbvios para o teste de unidade. Também há muito fanatismo quando se trata de testes unitários e prefiro uma abordagem muito mais pragmática à codificação e à vida em geral. Como contexto, atualmente estou escrevendo meu primeiro aplicativo "real", que é o onipresente mecanismo de blog usando o asp.net MVC. Estou seguindo vagamente a arquitetura MVC Storefront com meus próprios ajustes. Como tal, esta é minha primeira incursão real em objetos zombadores. Vou colocar o exemplo de código no final da pergunta.
Eu apreciaria qualquer insight ou recursos externos que eu pudesse usar para aumentar minha compreensão dos fundamentos de testes e zombarias. Os recursos que encontrei na rede geralmente são voltados para o "como" da zombaria e preciso de mais compreensão sobre onde, por que e quando zombar. Se este não é o melhor lugar para fazer essa pergunta, indique-me um lugar melhor.
Estou tentando entender o valor que estou obtendo dos seguintes testes. O UserService depende do IUserRepository. O valor da camada de serviço é separar sua lógica do armazenamento de dados, mas nesse caso a maioria das chamadas de UserService é passada diretamente para IUserRepository. O fato de não haver muita lógica real para testar também pode ser a fonte das minhas preocupações. Eu tenho as seguintes preocupações.
Parece que o código está apenas testando se a estrutura de simulação está funcionando.Para zombar das dependências, meus testes têm muito conhecimento da implementação do IUserRepository. Isso é um mal necessário?Que valor estou realmente ganhando com esses testes? A simplicidade do serviço em teste está me fazendo duvidar do valor desses testes.Estou usando o NUnit e o Rhino.Mocks, mas deve ser bastante óbvio o que estou tentando realizar.
[SetUp]
public void Setup()
{
userRepo = MockRepository.GenerateMock<IUserRepository>();
userSvc = new UserService(userRepo);
theUser = new User
{
ID = null,
UserName = "http://joe.myopenid.com",
EmailAddress = "[email protected]",
DisplayName = "Joe Blow",
Website = "http://joeblow.com"
};
}
[Test]
public void UserService_can_create_a_new_user()
{
// Arrange
userRepo.Expect(repo => repo.CreateUser(theUser)).Return(true);
// Act
bool result = userSvc.CreateUser(theUser);
// Assert
userRepo.VerifyAllExpectations();
Assert.That(result, Is.True,
"UserService.CreateUser(user) failed when it should have succeeded");
}
[Test]
public void UserService_can_not_create_an_existing_user()
{
// Arrange
userRepo.Stub(repo => repo.IsExistingUser(theUser)).Return(true);
userRepo.Expect(repo => repo.CreateUser(theUser)).Return(false);
// Act
bool result = userSvc.CreateUser(theUser);
// Assert
userRepo.VerifyAllExpectations();
Assert.That(result, Is.False,
"UserService.CreateUser() allowed multiple copies of same user to be created");
}