UnitTests:如何测试模拟不可行的依赖方法?

时间:2013-12-04 16:53:33

标签: c# unit-testing mstest

我对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 明确标记为公开。

3 个答案:

答案 0 :(得分:6)

通常,如果代码难以隔离以进行测试,则表明存在设计问题。

由于您在尝试测试的方法的上下文中多次调用HelperMethod,因此问题似乎是ActualMethod做得太多了。您可以通过将ActualMethod分解为以HelperMethod的输出作为参数的较小方法,然后对每个单独的方法进行单元测试来使其更具单元可测试性。

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

正如其他人所说,如果HelperMethod 私有并且未在课堂外使用,那么您可以忽略上述建议并确保HelperMethod经过测试确保通过公共接口覆盖每个合理的测试用例排列(例如ActualMethod)。但是,从根本上说,如果HelperMethod包含复杂的逻辑,那么它应该是独立的单元测试。

答案 1 :(得分:4)

如果MethodHelper是一个实现细节,因此是与ActualMethod在同一个类中的私有方法,那么我没有理由从ActualMethod单独测试它。您应该可以通过测试ActualMethod来实现全面覆盖。

答案 2 :(得分:0)

你能做的是:

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

如果HelperMethod的测试失败,您可以考虑ActualMethod作为未定义行为执行的任何操作,因此如果这些测试通过或失败则无关紧要。