首先,我不得不说,我是新手。所以也许我遗漏了一点。
我也刚刚开始习惯于TDD方法。
因此,在我的实际项目中,我正在业务层中的类上工作,而数据层尚未部署。我认为,这将是开始模拟的好时机。我正在使用Rhino Mocks,但我遇到的问题是在编写类本身之前需要了解类的实现细节。
Rhino Mocks检查是否实际调用了预期要调用的所有方法。因此,我经常需要首先知道被测试方法正在调用哪个模拟方法,即使它们可以以任何顺序调用。因此,在测试它们之前,我经常会编写复杂的方法,因为那时我已经知道调用方法的顺序。
简单的例子:
public void CreateAandB(bool arg1, bool arg2) {
if(arg1)
daoA.Create();
else throw new exception;
if(arg2)
daoB.Create();
else throw new exception;
}
如果要测试此方法的错误处理,则必须知道首先调用哪个方法。但是我不想在编写测试时就被实施细节所困扰。
我想念什么吗?
最佳答案
您有2个选择。如果该方法会导致类中的某些更改,则可以改为测试该方法的结果。因此,您可以先调用CreateAandB(true,false)
然后再调用其他方法来查看是否创建了正确的东西。在这种情况下,您的模拟对象可能是仅提供一些数据的存根。
如果doaA
和doaB
是注入到您的类中的对象,它们实际上在DB或类似数据库中创建数据,而您无法在测试中验证结果,那么您想测试与它们的交互,在这种情况下,您可以创建模拟并设置期望值,然后调用该方法并验证是否满足期望值。在这种情况下,您的模拟对象将是模拟对象,并将验证预期的行为。
是的,您正在测试实现细节,但是您正在测试方法是否正确使用其依赖关系的详细信息(这是您要测试的内容,而不是方法如何使用它们的依赖关系),而这些细节并不是您真正感兴趣的。
编辑
IDao daoA = MockRepository.GenerateMock<IDao>(); //create mock
daoA.Expect(dao=>dao.Create); //set expectation
...
daoA.VerifyExpectations(); //check that the Create method was called
您可以确保期望按特定顺序发生,但不使用我相信的AAA语法(source from 2009可能已经更改, EDIT see here对于可能适用于的选项),但是似乎有人开发了一种方法,可能允许这个here。我从未使用过,也无法验证。
至于需要知道首先调用哪个方法,以便可以验证异常,您有两种选择: