什么时候使用严格的嘲笑?

时间:2014-05-14 05:35:13

标签: unit-testing mocking tdd moq

我试图想出一个应该使用严格模拟的场景。我想不出任何一个。

你什么时候使用严格的模拟?为什么?

2 个答案:

答案 0 :(得分:5)

如果要验证是否已使用适当的参数调用了预期的方法,则使用正常(或松散)模拟。

严格模拟用于验证已调用预期方法而不是其他方法。把它们想象成一种负面的考验。

在大多数情况下,严格的嘲讽会使您的单位测试非常脆弱。即使您进行了少量的内部实施更改,测试也会失败。

但是,让我举一个可能有用的例子 - 测试一个要求,例如:

  

“获取缓存不应该命中数据库,如果它已包含数据”。

有很多方法可以通过松散的模拟来实现这一点,但是,简单地设置一个具有零预期函数调用的严格Mock<Database>非常方便。对此数据库的任何调用都将引发异常并使测试失败。


您希望使用严格模拟的另一种情况是AdapterWrapper设计模式。在这种模式中,您没有执行太多的业务逻辑。测试这些类的主要部分是是否使用正确的参数(而不是其他参数)调用了基础函数。在这种情况下,严格的模拟效果相当不错。

答案 1 :(得分:0)

我有一个简单的约定:

当被测系统(SUT)将调用委托给底层模拟层而不真正修改或应用传递给自身的参数时,使用严格的模拟。

当SUT将业务逻辑应用于传递给自身的参数并将一些派生/修改的值传递给模拟层时,使用松散的模拟。

例如:假设我们有数据库提供者StudentDAL,它有两种方法:

数据访问界面如下所示:

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

使用此DAL的实现如下所示:

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.

}