我是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,因此如果Help方法的函数有依赖项,则其UnitTest将失败。
事实上,如果我没有错的话,这就是嘲讽/依赖注入应该拯救的地方。
但在这个特定的案例中,我想测试几个(任意大的)边缘案例(这可能不是上面代码所必需的,但实际的ActualMethod实现是相当复杂的语法解析器的一部分)。由于HelperMethod在每次ActualMethodelperMethod调用来进行我的测试,这似乎令人难以忍受(现在只需想象所需HelperMethod调用的数量将是输入的二次方。)
我的问题是:如何优雅地测试一个将大量调用委托给另一个方法的方法?我真的应该嘲笑所有这些代表电话吗?或者我可以让方法测试依赖于其他方法的测试(比如Assert(HelperMethodPassed)?还是说没有办法改变实现的设计?
不幸的是,在ActualMethod中内联HelperMethod是不可能的,因为其他方法也依赖它。
提前谢谢,我真的很感激任何帮助!:)
PS:正在测试的项目是用C#编写的,我目前正在使用MSTest框架(但如果这能解决问题,我愿意切换到另一个框架)。
编辑:将HelperMethod和ActualMethod显式标记为公共。
一般来说,如果代码很难隔离进行测试,那么它就指向设计问题。
由于您在尝试测试的方法的上下文中多次调用HelperMethod
,所以问题似乎是ActualMethod
做得太多了。您可以将ActualMethod
分解为更小的方法,将HelperMethod
的输出作为参数,然后对这些单独的方法进行单元测试,从而使其更易于进行单元测试。
当然,您需要确保HelperMethod
也经过了单元测试!
正如其他人所说,如果HelperMethod
是private并且没有在类外使用,那么您可以忽略上述建议,并通过确保通过公共接口(例如ActualMethod
)覆盖测试用例的每个合理排列来确保HelperMethod
得到测试。不过,从根本上讲,如果HelperMethod
包含复杂的逻辑,那么它可能应该独立进行单元测试。
如果MethodHelper
是一个实现细节,因此是与ActualMethod
在同一类中的私有方法,那么我认为没有理由将其与ActualMethod
分开测试。您应该能够通过测试ActualMethod
来实现全覆盖。
您可以做的是:
- 测试
HelperMethod
,以便在单元测试中涵盖来自ActualMethod
的所有可能调用 - 然后假设
HelperMethod
是有效的,不要嘲笑它,但如果可以保证没有任何副作用,请使用实际的实现
如果HelperMethod
的测试失败,您可以将ActualMethod
所做的任何事情视为未定义的行为,因此这些测试通过或失败都无关紧要。