所以我有一个名为“Job”的类,它具有公共的和一个公共的Run()函数。课程中的所有内容都是私有的,封装在课堂中。 (你可能还记得这个Testing only the public method on a mid sized class?的一个老帖子,这个回复帮我很大)
这个Run()方法做了一大堆事情 – 将excel文件作为输入,从中提取数据,向第三方数据供应商发送一个请求,将结果存入数据库并记录数据库的开始/结束工作。
此Job类在其运行方法中使用3个独立的接口/类,(IConnection将连接到第三方供应商并发送请求,IParser将解析结果,IDataAccess将结果保存到数据库)。所以现在,我的Run()方法中唯一真正的逻辑是提取excel输入并将其发送到其他类的链。我创建了3个模拟课程,并在Job类ctor上使用DI,一切都很好,而且花花公子…
除了 – 我仍然有点失去了如何测试我的Run()方法 – 因为它是无效的,不返回任何东西…
在这种情况下,我应该向Run()方法添加返回值,该方法返回从Excel文件中提取了多少条记录?由于这是现在该功能中唯一的逻辑。这不会在真实的代码中处理,而是在单元测试中,这似乎对我来说有点臭 – 但是我是一个新手真正的TDD是关心…
第二个问题 – 我应该创建一个名为IExcelExtractor的第四个类,这对我来说是一个逻辑?还是这是一个类爆炸?
即使我做了后者,如果它返回void并且所有的工作都是被嘲笑的对象执行的,那么我如何测试我的Run()函数呢?我可以理解我的函数是否有一个有意义的返回值…但在这种情况下我是一个但困惑的。
非常感谢您阅读所有这一切,如果你这么做。
为了单独测试其行为受限于与协作者进行交互的类,您通常会传递模拟协作者对象,这些对象可以通过以您期望的方式调用方式进行检测。
如果您要为您在问题中提到的类手动(yuck!),可以创建一个实现IParser的MockParser类,并添加记录其方法调用方式的属性。
最好使用嘲弄的框架,即时创建嘲笑,指定对它们的期望,并验证这些期望。
这几天我一直在使用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();