Here’s my example:
[TestMethod]
public void NewAction_should_return_IndexAction()
{
NewViewModel viewModel = new NewViewModel()
{
Name = "José Inácio Santos Silva",
Email = "joseinacio@joseinacio.com",
Username = "joseinacio"
};
//IsUserRegistered is used to validate Username, Username is unique.
_mockAuthenticationService.Setup(x => x.IsUserRegistered(viewModel.Username )).Returns(false);
//IsUserRegistered is used to validate Email, Email is unique.
_mockUsuarioRepository.Setup(x => x.GetUserByEmail(viewModel.Email));
_mockDbContext.Setup(x => x.SaveChanges());
_mockUsuarioRepository.Setup(x => x.Add(It.IsAny<User>()));
_userController = new UserController(_mockUsuarioRepository.Object, _mockDbContext.Object, _mockAuthenticationService.Object);
ActionResult result = _userController.New(viewModel);
result.AssertActionRedirect().ToAction("Index");
_mockAuthenticationService.VerifyAll();
_mockUsuarioRepository.VerifyAll();
_mockDbContext.VerifyAll();
}
I have read some tutorials and they say that we should use only one mock per test.
But look at my test, it use 3 mocks, to check if my Action is working the right way I need to check these 3 mocks, do not agree?
How do I make this test in the correct way?
Each unit test should test only one thing.
In your unit test you are testing three mock objects. If the mockAuthenticationService fails, this will be reported and the unit test will stop there. Any errors with the other Mock objects are not reported and are effectively hidden.
In this situation you should create three unit tests, and in each one verify only one of the Mock objects. The rest are just used as stubs. (A stub is exactly the same as a Mock object, except you dont call VerifyAll on it at the end)
To avoid duplication and wasted effort, you should refactor that unit test so that most of the code is in a separate method. Each of the three unit tests calls this method and then verifies a single Mock.
You also have a test to ensure the correct redirect is called. This should also be in a separate test.
Quite simply: