我对UnitTesting很新,只是遇到了一个我不知道如何处理的情况,我很感激任何提示:)
情况如下,想象两种方法:
// simple standalone method
public bool HelperMethod(string substr) {
return substr.Equals("abc");
}
// complex method making (multiple) use of HelperMethod
public bool ActualMethod(string str) {
for (var i=0; i<str.Length; i++) {
var substr = str.Substring(i, 3);
if (HelperMethod(substr))
return true;
}
return false;
}
HelperMethod 函数没有依赖关系, ActualMethod 但是依赖于 HelperMethod ,因此如果 HelperMethod ',它的UnitTest将会失败一个人。
实际上,如果我没有弄错的话,这就是嘲讽/依赖注入应该来拯救的地方。
但在这个特定的情况下,我想测试几个(任意大的)边缘情况(上面的代码可能不需要,但实际的 ActualMethod 实现是相当复杂的语法分析器)。由于 HelperMethod 在每次 ActualMethod 调用中被多次调用,我将不得不为我的测试模拟数百个 HelperMethod 调用,这似乎无法忍受(现在想象一下,所需的 HelperMethod 调用的数量将是输入的二次方。)。
我的问题是:如何才能优雅地测试将大量调用委托给另一个方法的方法?我真的应该嘲笑所有这些委托电话吗?或者我可能允许进行方法测试取决于其他方法的测试(例如 Assert(HelperMethodPassed)?或者是否无法改变实现的设计?
不幸的是,无法在 ActualMethod 中内联 HelperMethod ,因为其他方法也依赖于它。
在此先感谢,我真的很感激任何帮助! :)
PS: 正在测试的项目是用C#编写的,我目前正在使用MSTest框架(但如果能解决问题,我可以切换到另一个框架)。
修改将 HelperMethod 和 ActualMethod 明确标记为公开。
答案 0 :(得分:6)
通常,如果代码难以隔离以进行测试,则表明存在设计问题。
由于您在尝试测试的方法的上下文中多次调用HelperMethod
,因此问题似乎是ActualMethod
做得太多了。您可以通过将ActualMethod
分解为以HelperMethod
的输出作为参数的较小方法,然后对每个单独的方法进行单元测试来使其更具单元可测试性。
当然,您还需要确保HelperMethod
也经过单元测试!
正如其他人所说,如果HelperMethod
私有并且未在课堂外使用,那么您可以忽略上述建议并确保HelperMethod
经过测试确保通过公共接口覆盖每个合理的测试用例排列(例如ActualMethod
)。但是,从根本上说,如果HelperMethod
包含复杂的逻辑,那么它应该是独立的单元测试。
答案 1 :(得分:4)
如果MethodHelper
是一个实现细节,因此是与ActualMethod
在同一个类中的私有方法,那么我没有理由从ActualMethod
单独测试它。您应该可以通过测试ActualMethod
来实现全面覆盖。
答案 2 :(得分:0)
你能做的是:
HelperMethod
,以便在单元测试中涵盖ActualMethod
的所有可能调用。HelperMethod
有效,不要嘲笑它,但如果你可以保证没有任何副作用,请使用实际的实现。如果HelperMethod
的测试失败,您可以考虑ActualMethod
作为未定义行为执行的任何操作,因此如果这些测试通过或失败则无关紧要。