我有一个类API,它具有完整的代码覆盖率,并使用DI模拟主类函数(Job.Run)中的所有逻辑,它完成所有工作。
我在生产中发现了一个错误,我们没有对其中一个数据输入字段进行验证。
所以,我添加了一个名为ValidateFoo()的存根函数...对这个函数写了一个单元测试来预测一个JobFailedException,运行测试 - 它显然失败了,因为该函数是空的。我添加了验证逻辑,现在测试通过。
太好了,现在我们知道验证工作了。问题是 - 如何编写测试以确保在Job.Run()中实际调用ValidateFoo()? ValidateFoo()是Job类的私有方法 - 因此它不是接口...
无论如何使用NMock2.0做到这一点?我知道TypeMock支持非接口类型的假货。但是现在改变模拟库不是一种选择。此时如果NMock不支持它,我只需将ValidateFoo()调用添加到Run()方法并手动测试 - 显然我不想考虑我的Job.Run()方法现在100%覆盖。任何建议?非常感谢,非常感谢。
编辑:我想到的另一个选择是为我的Job.Run功能创建一个集成测试(向它注入复合对象的真实实现而不是模拟)。我将为该字段给它一个错误的输入值,然后验证作业失败。这适用于我的测试 - 但它不是一个单元测试,而是一个测试一个功能单元的集成测试....嗯..
EDIT2:有没有办法做什么?有人有想法吗?也许TypeMock - 或更好的设计?
答案 0 :(得分:5)
The current version of NMock2可以使用最熟悉的语法来模拟具体类型(我不记得他们添加了哪个版本,但我们使用的是2.1版):
Job job = mockery.NewMock<Job>(MockStyle.Transparent);
Stub.On(job).Method("ValidateFoo").Will(Return.Value(true));
MockStyle.Transparent指定您不存在或期望的任何内容都应由底层实现处理 - 因此您可以存根并设置对您正在测试的实例的方法的期望。
但是,您只能对公共方法(和属性)进行存根和设置期望,这些方法也必须是虚拟的或抽象的。因此,为避免依赖集成测试,您有两种选择:
Job.ValidateFoo()
公开和虚拟。Job
。答案 1 :(得分:1)
由于所有私有都是由公共方法调用的(除非依赖于反射运行时执行),因此这些私有正由公共方法执行。除了简单地执行代码之外,这些私有方法导致对象的更改,例如设置类字段或调用其他对象。我找到了一种方法来获得调用私有方法的“结果”。 (或者嘲笑不应该在私有方法中执行的事情。)
我看不到正在测试的课程。另一个可能促使你想要访问私有方法的问题是它是一个超级大类,拥有大量私有功能。这些课程可能需要分解为较小的课程,其中一些课程可能会变成更简单的公共课程。