UnitTests:如何在mocking不可行的情况下测试依赖方法



我是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框架(但如果这能解决问题,我愿意切换到另一个框架)。

编辑:HelperMethodActualMethod显式标记为公共。

一般来说,如果代码很难隔离进行测试,那么它就指向设计问题。

由于您在尝试测试的方法的上下文中多次调用HelperMethod,所以问题似乎是ActualMethod做得太多了。您可以将ActualMethod分解为更小的方法,将HelperMethod的输出作为参数,然后对这些单独的方法进行单元测试,从而使其更易于进行单元测试。

当然,您需要确保HelperMethod也经过了单元测试!

正如其他人所说,如果HelperMethodprivate并且没有在类外使用,那么您可以忽略上述建议,并通过确保通过公共接口(例如ActualMethod)覆盖测试用例的每个合理排列来确保HelperMethod得到测试。不过,从根本上讲,如果HelperMethod包含复杂的逻辑,那么它可能应该独立进行单元测试。

如果MethodHelper是一个实现细节,因此是与ActualMethod在同一类中的私有方法,那么我认为没有理由将其与ActualMethod分开测试。您应该能够通过测试ActualMethod来实现全覆盖。

您可以做的是:

  • 测试HelperMethod,以便在单元测试中涵盖来自ActualMethod的所有可能调用
  • 然后假设HelperMethod是有效的,不要嘲笑它,但如果可以保证没有任何副作用,请使用实际的实现

如果HelperMethod的测试失败,您可以将ActualMethod所做的任何事情视为未定义的行为,因此这些测试通过或失败都无关紧要。

最新更新