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
// ...?
}
Arrange/Act/Assert (AAA) is a pattern for arranging and formatting code in Unit Test methods. It is a best practice to author your tests in more natural and convenient way.
It breaks each test down into three parts – Arrange, Act, and Assert – where each part is a step leading to the next. The arrange step sets up the test's input values. The act step prompts the primary function being tested. And finally, the assert step verifies that the output of the function is what was expected.
The AAA (Arrange-Act-Assert) pattern has become almost a standard across the industry. It suggests that you should divide your test method into three sections: arrange, act and assert.
The AAA (Arrange, Act, Assert) pattern is a common way of writing unit tests for a method under test. The Arrange section of a unit test method initializes objects and sets the value of the data that is passed to the method under test.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With