简体   繁体   English

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

[英]Unit testing a public method that calls multiple private methods

I want to test a public method that calls multiple private methods. 我想测试一个调用多个私有方法的公共方法。 What I read from all the answers to previously asked questions are varying. 我从先前提出的问题的所有答案中看到的内容是不同的。 Some say if one encounters such situation, then probably the structure is wrong, or methods that call other methods without any logic should not be tested, etc. 有人说,如果遇到这种情况,则可能是结构错误,或者不应测试没有任何逻辑的调用其他方法的方法,等等。

What is not clear for me is that, should I mock these private methods (using PowerMock or any reflection based library) and unit test just this method, or should I provide different types of inputs, so that all the cases will be tested, but private methods will be invoked as well. 我不清楚的是,我应该模拟这些私有方法(使用PowerMock或任何基于反射的库)并对此方法进行单元测试,还是应该提供不同类型的输入,以便对所有案例进行测试,但是私有方法也将被调用。 In the latter case, is it gonna be unit testing still, since I will call other methods, as well. 在后一种情况下,是否还要进行单元测试,因为我还将调用其他方法。

class ClassToTest {

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

            privateMethod2(argument);

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

}

First, it is important to understand that attempts to keep unit-test suites completely independent of implementation details is likely to result in inefficient test suites - that is, test suites that are not suited to find all bugs that could be found. 首先,必须理解,使单元测试套件完全独立于实现细节的尝试很可能会导致效率低下的测试套件-即,不适合查找所有可能发现的错误的测试套件。 And, finding bugs is one primary goal of testing (see Myers, Badgett, Sandler: The Art of Software Testing, or, Beizer: Software Testing Techniques, and many others). 而且,发现错误是测试的主要目标之一(请参阅Myers,Badgett,Sandler:软件测试的技巧,或Beizer:软件测试技术等)。

Alternative implementations of the same interface have different potential bugs. 同一接口的替代实现具有不同的潜在错误。 Tests for an iterative / recursive implementation of the fibonacci function will look different than for an implementation using the closed-form-expression from Moivre/Binet, or for a lookup-table implementation. 斐波那契函数的迭代/递归实现的测试与使用Moivre / Binet的封闭形式表达式的实现或查找表实现的测试看起来会有所不同。

There are, however, also secondary goals of unit-testing. 但是,还有单元测试的次要目标。 One of them is to avoid that your tests break unnecessarily when implementation details change. 其中之一是避免在实现细节更改时不必要地破坏测试。 Therefore, a test should not unnecessarily depend on implementation details. 因此,测试不应不必要地依赖于实现细节。 Always try first to create useful tests that are implementation agnostic, and later add the tests that are implementation specific. 始终首先尝试创建与实现无关的有用测试,然后再添加特定于实现的测试。 For the latter, testing internal (private) methods (for example by making them package visible) can also be a valid option - as long as you are aware of the disadvantages (test code maintenance will be needed if internal methods are renamed, deleted etc.) and weigh them against the advantages. 对于后者,测试内部(私有)方法(例如,通过使它们对程序包可见)也是一种有效的选择-只要您知道其缺点(如果内部方法被重命名,删除等,则需要维护测试代码) 。)并权衡其优势。

Second, very likely you should not mock the private methods, but just use them as part of their tests. 其次,很可能您不应该模拟私有方法,而应将其用作测试的一部分。 I say very likely, because it depends on the methods. 我说的可能性很大,因为这取决于方法。 Mocking should be done for a reason (and avoided otherwise). 应该出于某种原因进行模拟(否则应避免)。 Good reasons are: 有充分的理由是:

  • You can not easily make the depended-on-component (DOC) behave as intended for your tests. 您不能轻易使组件依赖(DOC)的行为符合测试的预期。
  • Does calling the DOC cause any non-derministic behaviour (date/time, randomness, network connections)? 调用DOC是否会引起任何非专业行为(日期/时间,随机性,网络连接)?
  • The test setup is overly complex and/or maintenance intensive (like, need for external files) 测试设置过于复杂和/或维护密集(例如,需要外部文件)
  • The original DOC brings portability problems for your test code. 原始DOC为您的测试代码带来了可移植性问题。
  • Does using the original DOC cause unnacceptably long build / execution times? 使用原始DOC是否会导致构建/执行时间过长?
  • Has the DOC stability (maturity) issues that make the tests unreliable, or, worse, is the DOC not even available yet? 是否存在使测试不可靠的DOC稳定性(成熟度)问题,或者更糟糕的是DOC尚不可用?

For example, you (typically) don't mock standard library math functions like sin or cos, because they don't have any of the abovementioned problems. 例如,您(通常)不模拟诸如sin或cos之类的标准库数学函数,因为它们没有上述任何问题。 You will have to judge whether this also holds for your private methods. 您将必须判断这是否也适用于您的私有方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM