对调用多个私有方法的公共方法进行单元测试

时间:2019-06-19 05:31:06

标签: java unit-testing junit

我想测试一个调用多个私有方法的公共方法。我从先前提出的问题的所有答案中看到的内容是不同的。有人说如果遇到这种情况,则可能是结构错误,或者不应测试没有任何逻辑的调用其他方法的方法,等等。

我不清楚的是,我应该模拟这些私有方法(使用PowerMock或任何基于反射的库)并对该方法进行单元测试,还是应该提供不同类型的输入,以便所有情况都可以测试,但私有方法也会被调用。在后一种情况下,是否还要进行单元测试,因为我还将调用其他方法。

class ClassToTest {

    public void publicMethod (Argument argument) {
        try {
            privateMethod1();

            privateMethod2(argument);

            privateMethod3();
        } catch (Exception ex) {
            privateMethod4();
        }
    }

}

1 个答案:

答案 0 :(得分:1)

首先,必须理解,使单元测试套件完全独立于实现细节的尝试很可能导致效率低下的测试套件-即,不适合查找所有可能发现的错误的测试套件。而且,发现错误是测试的一个主要目标(请参阅Myers,Badgett,Sandler:软件测试的技巧,或Beizer:软件测试技术等)。

同一接口的替代实现具有不同的潜在错误。斐波那契函数的迭代/递归实现的测试与使用Moivre / Binet的封闭形式表达式的实现或查找表实现的测试看起来有所不同。

但是,还有单元测试的次要目标。其中之一是避免在实现细节更改时不必要地破坏测试。因此,测试不应不必要地依赖于实现细节。始终首先尝试创建与实现无关的有用测试,然后再添加特定于实现的测试。对于后者,测试内部(私有)方法(例如,通过使它们对程序包可见)也是一种有效的选择-只要您知道其缺点(如果内部方法被重命名,删除等,则需要维护测试代码) 。然后权衡优势。

第二,很可能您不应该模拟私有方法,而应将它们用作其测试的一部分。我说的可能性很大,因为这取决于方法。应该出于某种原因进行模拟(否则应避免)。充分的理由是:

  • 您不能轻易地使组件依赖(DOC)的行为符合测试的预期。
  • 调用DOC是否会引起任何非专业行为(日期/时间,随机性,网络连接)?
  • 测试设置过于复杂和/或需要大量维护(例如需要外部文件)
  • 原始DOC为您的测试代码带来了可移植性问题。
  • 使用原始DOC是否会导致构建/执行时间过长?
  • 是否存在使测试不可靠的DOC稳定性(成熟度)问题,或者更糟糕的是,甚至还没有DOC?

例如,您(通常)不模拟诸如sin或cos之类的标准库数学函数,因为它们没有上述任何问题。您必须判断这是否也适用于您的私有方法。