Generally speaking, @KonradMorawski's answer is good and complete. However, I would like to add that there is one scenario that I would consider it valuable to mock static
methods - the static
factory method.
Personally, in my code I very infrequently use static
factory methods; I only use them if the created object is stateless, the factory is stateless, and the created object has no dependencies - and even then I'm still not very likely most of the time. Otherwise, I use an instance of a factory object, which can then be mocked.
The issue with using a static
factory method as provided is that the created objects will not be mock
s or spy
s, which means you will not be able to call verify
on them, and you will not control access to these objects in advance. For example consider a math application like the following:
public abstract class ComplexNumber {
private double realPart;
private double imaginaryPart;
ComplexNumber(double realPart, double imaginaryPart) {
this.realPart = realPart;
this.imaginaryPart = imaginaryPart;
}
public static ComplexNumber create(double realPart, double imaginaryPart) {
return new ComplexNumber(realPart, imaginaryPart);
}
}
public class RootCalculator {
// Whatever is appropriate
public List<ComplexNumber> roots(double... coefficients) {
// somewhere in the code
ComplexNumber number = new ComplexNumber(something, somethingElse);
// blah blah
}
}
public class RootCalculatorTest {
@Test
public testCalculator() {
RootCalculator calc = new RootCalculator();
List<ComplexNumber> roots = calc.roots(1, 0, 1); // equivalent to x^2 + 1 = 0
for(ComplexNumber number : roots) {
// verify(...);
}
}
}
Note that you can't call verify
on the returned complex numbers, nor can you verify
that the factory method itself was called the correct number of times. With PowerMock you can do both. Note that using PowerMock here is superior to just calling new ComplexNumber()
.
Of course the best way to do it is just inject an instance of a factory, which can then be mocked, avoiding PowerMock and allowing you to do all the normal testing behavior.