Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Having recently returned from a Test Driven Development (TDD) course I had the following thought.

While writing unit tests using Mockito we came up against of the problem of mocking static methods. It was suggested by one developer we use PowerMock, which allows mocking of static methods, and then we got into a big discussion on how we should approach this problem.

However, in my experience static methods should only really be used as utility type methods. The classic example in java being Math.random().

So a static method should only, execute one defined action regardless of any interaction with a class instance. If this is not the case, and you require class instance interaction, your method should not be static and you need to rethink your design.

So my question is, with this in mind should you need to mock static methods at all? If they are always performing a simple action, then surely you should just call them as you would in real code.

share|improve this question

3 Answers 3

So my question is, with this in mind should you need to mock static methods at all? If they are always performing a simple action, then surely you should just call them as you would in real code.

Yes, if the code is properly written. Sometimes it isn't, and you still need to test it. Refactoring can be very time-consuming (statics are typically associated with high coupling and other no-nos), so this is kind of a workaround.

Refactoring could be not only unfeasible, but impossible. The static method might be out of your reach - what if your code has to call a static method from a third party library, and it's not stateless, takes a long time to execute, has special requirements (database, web access)... In order to test your code you need to mock this method.

share|improve this answer

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 mocks or spys, 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.

share|improve this answer
    
The complex number is a ValueObject, normally VO are never mocked (its like mocking a string or Integer). –  AlfredoCasado Mar 7 at 13:59

Mock static methods is a bad idea, i use only if i'm testing legacy code and i can't refactor for whatever reason. But in a normal development TDD cycle its a bad smell.

I always remembers one phrase from Ian Cooper "test things you want to preserve", when you are mocking a static you are stating in our test that do you want to preserve not the functionality, you want to preserve this design with a static method call. Are you sure you want to preserve this?

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.