Reputation: 1829
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. 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();
}
}
}
Upvotes: 1
Views: 1853
Reputation: 5939
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).
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.
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:
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. You will have to judge whether this also holds for your private methods.
Upvotes: 1