Bhuvan
Bhuvan

Reputation: 2229

How to mock static methods with mockito?

I am using mockito for the Junits

I know mockito donot mock static methods but is there a way around for this instead of using powermock?

Thanks

Upvotes: 3

Views: 8096

Answers (4)

Alex Shesterov
Alex Shesterov

Reputation: 27525

Mockito supports mocking static methods since version 3.4.0. And it does the job better than PowerMock by limiting the scope of the static method mock.

To use this feature, you must enable Mockito's inline mock maker by adding the following file into the test-classpath:

/mockito-extensions/org.mockito.plugins.MockMaker

The contents of the file must be the following single line:

mock-maker-inline

When you've done this, you can mock final classes and static methods.

Here an example of how to mock static methods with and without arguments:

public class Foo {
    public static String voidMethod() {
        return "voidMethod-return";
    }

    public static String intMethod(int x) {
        return "intMethod-return " + x;
    }
}

...

// Prepare class 'Foo' for static mocking, for the current thread: 
try (MockedStatic<Foo> mocked = Mockito.mockStatic(Foo.class)) {

        //////////
        // Mock 'Foo.voidMethod()' to return "voidMethod-mock":
        mocked.when(Foo::voidMethod).thenReturn("voidMethod-mock");

        assertEquals("voidMethod-mock", Foo.voidMethod());
        mocked.verify(Foo::voidMethod);


        //////////
        // Mock 'Foo.intMethod()' to return "intMethod-mock":
        mocked.when(() -> Foo.intMethod(10)).thenReturn("intMethod-mock 10");

        assertEquals("intMethod-mock 10", Foo.intMethod(10));
        mocked.verify(() -> Foo.intMethod(10));

} // MockedStatic.close() releases the static mock.

// The original static method is 'restored' here: 
assertEquals("voidMethod-return", Foo.voidMethod());
assertEquals("intMethod-return 10", Foo.intMethod(10));

Upvotes: 0

bric3
bric3

Reputation: 42223

Possible workaround would be to encapsulate static methods in real instance I think. Or real instance behind the static method.

Though that would mean you'll have to modify your production code.

Honestly if you ask yourself this question now, you are testing your code too late in the development process. (Now evangelizing ;)) If you were practicing TDD, you would have noticed this issue early, and tweaked your design early to be fully testable with classic testing software.

I personally use the "pain metrics" when practicing TDD to see if my design is ok or not. Of course everything depends on the context, but usually this is a good indicator of good design (at least for me and some others).

So my advice get rid of these static methods or revise your design to not be dependent on static method mocking.

Cheers

Upvotes: 5

gontard
gontard

Reputation: 29510

No i think there isn't any way to do this withour PowerMock.

But you could break the dependency on this static methods, by introducing an adapter.

Upvotes: 1

pap
pap

Reputation: 27614

Not sure what "way around" you are looking for. A lot of people use both Mockito and Powermock together and I've not heard any horror-stories about incompatibilities or conflicts. Just use Powermock in those instances where you need to mock static methods and you should be ok.

Or refactor to not use static methods in a way that requires mocking.

Upvotes: 1

Related Questions