Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito asks to add @PrepareForTest for the class even after adding @PrepareForTest

I have the following simple code. I have a class (TestClass) and I want to test "someMethod". There is an external static method which is called by my "someMethod". I want to Powermock that static method to return me some dummy object. I have the @PrepareForTest(ExternalClass.class) in the begining, but when I execute it gives the error:

The class ExternalClass not prepared for test. To prepare this class, add class to the '@PrepareForTest' annotation. In case if you don't use this annotation, add the annotation on class or method level.

Please help me to point out what is wrong with the way I have used @PrepareForTest

@RunWith(PowerMockRunner.class)
@PrepareForTest(ExternalClass.class)
public class xyzTest {  
    @Mock
    private RestTemplate restTemplate;

    @Mock
    private TestClass testClass;

    @BeforeClass
    private void setUpBeforeClass() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testSuccessCase() {
        Boolean mockResponse = true;
        ResponseEntity<Boolean> response = new ResponseEntity<Boolean>(mockResponse, HttpStatus.OK);
        SomeClass someClass = new SomeClass("test", "1.0.0", "someUrl", "someMetaData");

        PowerMockito.mockStatic(ExternalClass.class);

        Mockito.when(restTemplate.postForEntity(any(String.class), any(String.class), eq(Boolean.class))).thenReturn(response);
        Mockito.when(ExternalClass.getSomeClass(any(String.class))).thenReturn(someClass);

        Boolean result = testClass.someMethod("test");

        Assert.isTrue(result);
        Mockito.verify(restTemplate, times(1)).postForObject(any(String.class), any(String.class), any());
    }
}
like image 337
ViV Avatar asked Jun 20 '16 14:06

ViV


3 Answers

Make sure you add @RunWith(PowerMockRunner.class) to the top of your class as well.

::edit:: two years later...

Don't ever use PowerMockito, you shouldn't need to.

If you do need to, you have most likely broken the SOLID principles and your design is wrong.

Fix your design instead.

like image 167
wild_nothing Avatar answered Nov 12 '22 10:11

wild_nothing


As with the last answer, my problem was also mixing the Test annotation from TestNG instead of Junit Test.

import org.junit.Test; // works

import org.testng.annotations.Test // did not work

Very abstruse error and I spent more than 5 hrs debugging :(

like image 16
user2121316 Avatar answered Nov 12 '22 11:11

user2121316


For those trying to get this working with Junit 5, If your using the powermock-module-junit4 beta release which claims to be compatible with 4+, the library will still not recognize:

import org.junit.jupiter.api.Test;

and it will throw a:

org.powermock.api.mockito.ClassNotPreparedException

when @PrepareForTest is applied on the class you want to static mock. If you want to use PowerMock, you will have to go back to Junit 4 or create a MockWrapper for your static method at this time.

PowerMock 2.0: Github Roadmap

like image 13
Aaron Tobias Avatar answered Nov 12 '22 12:11

Aaron Tobias