I'm using Moq
to test behaviour of some void methods. Using MockBehaviour.Strict
every call to the mock must be specified during Arrange
step. This is resulting in a lot of tests not having any Assert
(or Verify) step. The pass condition is simply that the test ran without throwing an exception. Am I missing something? Is the Arrange, Act, Assert
pattern unsuitable when using strict mocks? Is there a more semantic way to layout these tests?
A trivial made up example...
[TestClass]
public void DeleteUser_ShouldCallDeleteOnRepository()
{
// Arrange
var userRepository = new Mock<IUserRepository>(MockBehavior.Strict);
int userId = 9;
userRepository.Setup(x => x.Delete(userId));
var controller = new UserController(userRepository.Object);
// Act
controller.DeleteUser(userId);
// Assert
// ...?
}
Your mock is taking the place of a collaborator. It's ideally doing one of two things:
When the mock is providing information or data, it's enough that this should be a stub. You can set up the return value of the mock to the information required. This should be part of Arrange.
When the mock is doing a job, the delegation can be verified. This is why you have Assert.
What you're doing with the strict interaction is ensuring that every single interaction is expected, basically saying, "Here's what I expect to happen, and if anything else happens it's wrong." This is a different kind of testing to Act, Arrange, Assert, which says, "In this context, when I do this stuff, then I should get this outcome."
With a "nice" mock, you only need to worry about the interactions you're interested in. So, for instance, if I'm a controller and I'm looking up some information in one repository, validating it with a validator, then saving the result in another repository, I might have several tests:
With the strict mock, you have to do all the expectations, even if all you're interested in is the "save". By using a nice mock, we can split up the different aspects of behavior and only focus on one of them in each test.
As an additional bonus, nice mocks allow you to do:
Whereas strict mocks make you do:
The first of these is generally considered more readable.