Bry*_*owe 49 .net c# unit-testing moq mocking
在过去,我只使用了Rhino Mocks,典型的严格模拟.我正在与Moq合作开展一个项目,我想知道正确的用法.
假设我有一个方法Bar的对象Foo,它在对象Buzz上调用Bizz方法.
在我的测试中,我想验证Bizz是否被调用,因此我觉得有两种可能的选择:
用严格的模拟
var mockBuzz= new Mock<IBuzz>(MockBehavior.Strict);
mockBuzz.Setup(x => x.Bizz()); //test will fail if Bizz method not called
foo.Buzz = mockBuzz
foo.Bar();
mockBuzz.VerifyAll();
Run Code Online (Sandbox Code Playgroud)
随着一个松散的模拟
var mockBuzz= new Mock<IBuzz>();
foo.Buzz = mockBuzz
foo.Bar();
mockBuzz.Verify(x => x.Bizz()) //test will fail if Bizz method not called
Run Code Online (Sandbox Code Playgroud)
有这样做的标准或正常方式吗?
And*_*wry 75
当我第一次在单元测试中使用模拟时,我曾经使用严格的模拟.这不会持续很长时间.我停止这样做有两个原因:
因此,我强烈建议在单元测试中使用松散的模拟.
Ben*_*ict 18
我有C++ /非.NET开发的背景,最近我更喜欢.NET,所以当我第一次使用Moq时,我有一些期望.我试图理解WTF继续我的测试以及为什么我测试的代码抛出一个随机异常而不是Mock库告诉我代码试图调用哪个函数.所以我发现我需要打开严格的行为,这是令人困惑的 - 然后我遇到了这个问题,我看到这个问题还没有回答.
在宽松的模式,而事实上,它是默认的是疯狂的.Mock库的重点是什么,它完全不可预测,你没有明确列出它应该做什么?
我完全不同意支持松散模式的其他答案中列出的要点.没有充分的理由使用它,我永远不会想要.在编写单元测试时,我想确定发生了什么 - 如果我知道函数需要返回null,我会让它返回.我希望我的测试是脆弱的(在重要的方式),以便我可以修复它们并添加到测试代码套件中的设置行,这些是明确的信息,它正在向我描述我的软件将做什么.
问题是 - 是否有标准和正常的方式来做到这一点?
是的 - 从一般编程的角度来看,即其他语言和.NET世界之外,你应该始终使用Strict.善良知道为什么它不是Moq的默认值.
我有一个简单的约定:
当被测系统(SUT)将调用委托给底层模拟层而不真正修改或应用传递给自身的参数的任何业务逻辑时,使用严格的模拟.
当SUT将业务逻辑应用于传递给自身的参数并将一些派生/修改的值传递给模拟层时,请使用松散的模拟.
例如:假设我们有数据库提供程序StudentDAL,它有两种方法:
数据访问界面如下所示:
public Student GetStudentById(int id);
public IList<Student> GetStudents(int ageFilter, int classId);
Run Code Online (Sandbox Code Playgroud)
使用此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.
}
Run Code Online (Sandbox Code Playgroud)
就我个人而言,作为嘲笑和最小起订量的新手,我觉得从严格模式开始有助于更好地理解内部结构和正在发生的事情。“松散”有时会隐藏细节并通过最小起订量初学者可能看不到的测试。一旦你掌握了你的模拟技巧 - 松散可能会更有效率 - 就像在这种情况下用“设置”保存一行并只使用“验证”代替。