单元测试:需要模拟类本身的方法吗?

时间:2017-03-21 14:05:36

标签: unit-testing

我一直在进行一些单元测试,并且只是进入整个主题。

我偶然发现了以下情况,假设我有一个这样的课程:

class A{
  public B mehtod_1(B b){
    b = method_2(b);
    b = method_3(b);
    b += 1; 
    return b;
  }

  public B method_2(B b){
    // do something to B without external dependency
    return B;
  }

  public B method_3(B b){
    // do something else to B without external dependency
    return B;
  }
}

我可以毫无问题地为method_2method_3编写测试,通过以不同方式配置B并在调用后断言B上的预期转换来执行不同的测试,这些方法是原子的。

所以我的问题是:

如果我以原子方式测试method_1,我将不得不模拟对method_2method_3的调用,因为如果我实际上调用这些方法,我就不会测试{{ 1}}在一个原子庄园里。

在后一种情况下method_1被打破,method_2method_1的测试会中断,这会产生误导。如果我在method_2测试中模拟method_2调用,则只有method_1测试会失败,从而更清楚地指示错误的位置(即业务逻辑中的某处)如果所有其他调用的方法按预期工作,则为method_2

我是否正确理解了这个概念?

另一方面,如果两个测试都失败,那是正确的,因为在现实世界中,method_1无法在method_1工作的情况下工作。

我的直觉是说测试的原子性是所期望的,这意味着第一个解决方案,其中method_2有一个测试,method_1method_2的每个可能结果(静态模拟) )。

是否有"正确" /普通/最佳做法?

1 个答案:

答案 0 :(得分:1)

立即回答:如果我们在这里谈论Java; 部分嘲笑对你很感兴趣,你可以考虑使用Mockito的spy概念。

但除此之外:你的单元测试错误了。你所谓的 atomicity ;我打电话给担心实施细节。但它并不重要"究竟是什么"那个"测试方法"实际上。您想测试 ,而不是如何

含义:如果该方法必须调用其他方法(在单元测试环境中正常工作;不进行模拟);那么就没有必要考虑嘲笑它们了!

您会看到:您关心每种方法的合同。那个合约是你要测试的:给出这些输入参数,我期待那个结果/副作用/异常......

尽管如此,您有多个公共方法;并且他们以某种方式相互依赖可能表示设计问题(如:它们是否全部公开有意义;是否有一些隐藏在界面中的抽象,你应该更好地表达在其他方面?)。但这只能在真实代码的情况下决定;真实的背景。