Search code examples
javamockitojunit4powermockpowermockito

How to mock class level method declaration using Mockito


I have a test class as below through which i am trying to replicate my current issue.

public class EmployeeResource{
public EmployeeAPI restApi = (EmployeeAPI) EmpRegistrar.getInterface(EmployeeAPI.class); // getInterface is a static method.

public Employee addEmployee( Employee emp){
if(Objects.isNull(emp)) {
restApi.notifyAudit(); // suppose this is some existing legacy code which we don't want to run while running junit.
throw new APIException(CLIENT_ERROR_BAD_REQUEST, “Incorrect Post Request”);
}
// Implementation
}

Now i have Junit for this class.

@RunWith(PowerMockRunner.class)
@PrepareForTest({ EmpRegistrar.class })
public class EmployeeResourceTest {

@Before
public void setup() throws Exception {
PowerMockito.mockStatic(EmpRegistrar.class);
EmployeeAPI restApi= Mockito.mock(EmployeeAPI.class);
PowerMockito.when(EmpRegistrar.getInterface(EmployeeAPI.class)).thenReturn(restApi);
PowerMockito.doNothing().when(restApi).notifyAudit();
}

@Test
public void testAddEmployee_Invalid() throws Exception {
EmployeeResource employeeResource = new EmployeeResource();
 try {
employeeResource.addEmployee(null);
}
catch (Exception e) {
assertTrue(e instanceof APIException);
assertEquals("Incorrect Post Request", e.getMessage());
}
}
}

So when I run the above junit, I do not get the mocked instance of restApi object and get it as null which gives NullPointerException on the below line

restApi. notifyAudit(); // when it runs through junit.

Just to verify, when I add the line restApi = (EmployeeAPI) EmpRegistrar.getInterface(EmployeeAPI.class); inside the addEmployee method itself , I get the mocked instance and the test case pass.

So just want to check with all you folks, that as the object instance for restApi is obtained at class level, I am not able to get the mocked instance of that through mockito as the scope of mockito is for that method itself.Or is there any way i can achieve the same.

This is an existing old code which for which i am writing junit in my project. I tried to replicate the same through above sample test code.So let me know if i am not clear at any place.

Thanks -Sam


Solution

  • with powermock:

    EmployeeResource employeeResource = new EmployeeResource();
    Whitebox.setInternalState(employeeResource, restApi);
    

    and if you have the dependency spring-test:

    EmployeeResource employeeResource = new EmployeeResource();
    ReflectionTestUtils.setField(employeeResource, "restApi", restApi);