dfe*_*aro 23 tdd unit-testing mocking
我在这个具体问题的教程中找不到多少..
所以我有一个名为'Job'的类,它有公共ctors和一个公共Run()函数.类中的所有内容都是私有的,并封装在类中.(你可能还记得这里的老帖子只测试中型班级的公共方法吗?这些回复对我帮助很大)
这个Run()方法做了很多事情 - 将excel文件作为输入,从中提取数据,向第三方数据供应商发送请求,获取结果并将其放入数据库并记录开始/结束工作.
此Job类在其run方法中使用3个单独的接口/类,(IConnection将连接到第三方供应商并发送请求,IParser将解析结果,IDataAccess将结果保存到数据库).所以现在,我的Run()方法中唯一真正的逻辑是提取excel输入并将其发送到其他类的链中.我创建了3个模拟类,并在Job类ctor上使用DI,一切都很好,花花公子......
除了 - 我仍然有点失去了如何测试我的Run()方法 - 因为它是无效的,并没有返回任何东西......
在这种情况下,我应该向Run()方法添加一个返回值,该方法返回从Excel文件中提取的记录数量吗?因为这是现在该函数中唯一完成的逻辑..这不会在实际代码中处理,但会在单元测试中...这对我来说似乎有点臭 - 但我是一个新的真正的TDD关注......
第二个问题 - 我应该创建一个名为IExcelExtractor的第四个类,它为我做了那个逻辑吗?或者这是一类爆炸?
即使我做了后者,如果它返回void我将如何测试我的Run()函数,并且它的所有工作都是由真正无效的模拟对象执行的?我能理解我的函数是否有一个有意义的返回值......但在这种情况下我很困惑.
非常感谢你阅读所有这些,如果你做到这一点.
Jef*_*nal 18
您所描述的通常称为行为验证(与状态验证相对).它有它的支持者和批评者,但对于几类课程,它是城里唯一的游戏,如果你想进行单元测试.
要对其行为仅限于与协作者交互的类进行单元测试,通常会传递模拟协作者对象,这些对象的检测方式允许您以预期的方式验证其方法是否已被调用.
如果您要为您在问题中提到的类手动执行此操作(哎呀!),您可以创建一个MockParser实现IParser并添加属性的类,以记录调用其方法的方式和方式.
最好使用模拟框架,即动态创建模拟,指定它们的预期,并验证这些期望.
这些天我一直在使用NMock2,测试看起来像这样:
// 'mockery' is the central framework object and Mock object factory
IParser mockParser = mockery.NewMock<IParser>();
// Other dependencies omitted
Job job = new Job(mockParser);
// This just ensures this method is called so the return value doesn't matter
Expect.Once.On(mockParser).
.Method("Parse").
.WithAnyArguments().
.Will(Return.Value(new object()));
job.Run();
mockery.VerifyAllExpectationsHaveBeenMet();
Run Code Online (Sandbox Code Playgroud)
当你注入一个mock时,你会向Run类的构造函数传递一个测试类,如果测试通过,你会询问它.例如,根据您在构造函数中传递的excel文件,您可以测试IParser mock是否获得了正确的请求.您可以通过自己的类来完成此操作,并在其中收集结果并测试其收集的内容,或者您可以通过模拟框架来实现此目的,该模板框架为您提供了在不构建类的情况下表达此类测试的方法.
我看到你用tdd标记了你的问题,但是在真正的tdd中你没有真正得到这个问题(你这样做,但提出了不同的要求)因为你首先构建测试,它定义了接口,而不是构建类接口然后想你怎么去测试这个东西.需要测试驱动设计.您仍然使用相同的技术(在这种情况下可能最终使用相同的设计),但问题会有所不同.
| 归档时间: |
|
| 查看次数: |
16224 次 |
| 最近记录: |