Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I easily mock out a static method in Java (jUnit4)

How do I easily mock out a static method in Java?

I'm using Spring 2.5 and JUnit 4.4

@Service
public class SomeServiceImpl implements SomeService {

    public Object doSomething() {
        Logger.getLogger(this.class); //a static method invoked.
        // ...
    }
}

I don't control the static method that my service needs to invoke so I cannot refactor it to be more unit-testable. I've used the Log4J Logger as an example, but the real static method is similar. It is not an option to change the static method.

Doing Grails work, I'm used to using something like:

def mockedControl = mockFor(Logger)
mockControl.demand.static.getLogger{Class clazz-> … }
…
mockControl.verify()

How do I do something similar in Java?

like image 723
Colin Harrington Avatar asked Jul 29 '09 21:07

Colin Harrington


2 Answers

Do you mean you can't control the calling code? Because if you control the calls to the static method but not the implementation itself, you can easily make that testable. Create a dependency interface with a single method with the same signature as the static method. Your production implementation will just call through to the static method, but anything which currently calls the static method will call via the interface instead.

You can then mock out that interface in the normal way.

like image 176
Jon Skeet Avatar answered Sep 17 '22 11:09

Jon Skeet


The JMockit framework promises to allow mocking of static methods.

https://jmockit.dev.java.net/

In fact, it makes some fairly bold claims, including that static methods are a perfectly valid design choice and their use should not be restricted because of the inadequacy of testing frameworks.

Regardless of whether or not such claims are justifiable, the JMockit framework itself is pretty interesting, although I've yet to try it myself.

like image 38
skaffman Avatar answered Sep 18 '22 11:09

skaffman