How do I use PowerMockito to return a mock object from a final static class

11,164

You're missing the annotation @PrepareForTest and the use of mockStatic() which are required when you wish to mock a final static class with PowerMockito. I think where you might be getting confused is that you're dealing with a final static class and not only a final class, so there are a few additional mock calls you need to be aware of.

Given these implementation classes

/*
The final static class that's giving you all the mocking grief
*/
public final class FinalStaticClass {

    // this object instance "will not" be returned when we mock() the class
    private static MyObject obj = new MyObject();

    public static MyObject getMyObject() {
        return obj; 
    }
}

/*
A simple value object used by MyClass
*/
public class MyObject {

}

/*
The class you wish to test
*/
public class MyClass {

    private MyObject obj;

    public void methodToTest() {
        obj = FinalStaticClass.getMyObject();
        // do something
    }

    public MyObject getMyObject() {
        return obj;
    }
}

Make sure you include powermock-mockito-1.4.10-full.jar in your project, then you can use this test class

import static org.junit.Assert.assertEquals;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;

import ...    

@RunWith(PowerMockRunner.class)
@PrepareForTest(FinalStaticClass.class)
public class MyClassTest{

    @Mock
    MyObject expectedObject;

    @InjectMocks
    MyClass myClass = new MyClass();

    @Test
    public void test1(){

        // mock all static methods
        mockStatic(FinalStaticClass.class);

        when(FinalStaticClass.getMyObject()).thenReturn(expectedObject);

        // execute the method under test
        myClass.methodToTest();

        assertEquals(expectedObject, myClass.getMyObject());

    }
}

You can see that expectedObject is a mock that you have created in the test and not the implementation returned from FinalStaticClass

Share:
11,164
user1513941
Author by

user1513941

Updated on June 06, 2022

Comments

  • user1513941
    user1513941 about 2 years

    Hey I'm using Mockito and TestNG to write a unit test for a class that's making a lot of external calls to a service, I'm actually quite new to this hence I seem to be stuck with little documentation on the net for my exact problem.

    my test looks like this basically

    @Test
    public class ClassToTestTest{
    
    @Mock
    private Object1 object1;
    
    @Mock
    private Object2 object2;
    
    @InjectMocks
    private ClassToTest classToTest;
    
    public void test1(){
        classToTest.methodToTest();
    
    }
    ...
    ...
    }
    

    The actual class is as follows

    import FinalClass;
    
    public class ClassToTest{
    
    private Object1 object1;
    private Object2 object2;
    
    public void methodToTest(){
        object2 = FinalClass.getObject2();
    
        ...
        ...
    }
    
    ...
    ...
    }
    

    I just need FinalClass.getObject2() to return the mock of Object2 That I've created in my Test, I know I can mock FinalClass using PowerMock, but I'm not quite getting how to inject it in the classToTest that I've created, so that when I run the classToTest.methodToTest() from my test object2 is initialized with my mocked implementation.

    Thanks in Advance!