I am trying to come up with scenario in which one should use strict mocks. I can't think of any.

When do you use strict mocks and why?

有帮助吗?

解决方案

Normal (or loose) mocks are used when you want to verify that an expected method has been called with the proper parameters.

Strict mocks are used to verify that only the expected methods have been called and no other. Think of them as a kind of negative test.

In most cases, having strict mocks makes your unit tests very fragile. Tests start failing even if you make a small internal implementation change.

But let me give you an example where they may be useful - testing a requirement such as:

"A Get on a cache should not hit the database if it already contains data".

There are ways to achieve this with loose mocks, but instead, it is very convenient to simply set up a strict Mock<Database> with zero expected function calls. Any call to this database will then throw an exception and fail the test.


Another scenario where you would want to use strict mocks is in an Adapter or Wrapper design pattern. In this pattern, you are not executing much business logic. The major part of testing these classes is whether the underlying functions have been called with the correct parameters (and no other). Strict mocks work fairly well in this case.

其他提示

I have a simple convention:

Use strict mocks when the system under test (SUT) is delegating the call to the underlying mocked layer without really modifying or applying any business logic to the arguments passed to itself.

Use loose mocks when the SUT applies business logic to the arguments passed to itself and passes on some derived/modified values to the mocked layer.

For eg: Lets say we have database provider StudentDAL which has two methods:

Data access interface looks something like below:

Student GetStudentById(int id);
IList<Student> GetStudents(int ageFilter, int classId);

The implementation which consumes this DAL looks like below:

public Student FindStudent(int id)
{
   //StudentDAL dependency injected
   return StudentDAL.GetStudentById(id);
   //Use strict mock to test this
}
public IList<Student> GetStudentsForClass(StudentListRequest studentListRequest)
{
  //StudentDAL dependency injected
  //age filter is derived from the request and then passed on to the underlying layer
  int ageFilter = DateTime.Now.Year - studentListRequest.DateOfBirthFilter.Year;
  return StudentDAL.GetStudents(ageFilter , studentListRequest.ClassId)
  //Use loose mock and use verify api of MOQ to make sure that the age filter is correctly passed on.

}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top