I have source code like below.
public class XYZClass {
private static InitialContext ctx;
private static InitialContext getCtx(){
try{
if(ctx == null)
ctx = new InitialContext();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return ctx;
}
public static IMFTPManagerService getIMFTPManagerFacade() {
try {
return (IMFTPManagerService) getCtx().lookup("abc");
} catch (Exception e) {
return null;
}
}
}
I am trying to write test case for getIMFTPManagerFacade()
method. I need to mock getCtx()
method which is private and static and also lookup("abc")
method. So I did it in the below way. I am not getting any error or any exception in mocking. Also when I debug the line individual method return values, the getCtx()
method is returning the mocked object and lookup()
method is also returning the required mocked object. But after completing the execution of that entire line return (IMFTPManagerService) getCtx().lookup("abc");
, the line returns null to the test class method. Can any one find me a solution? If my question is not clear, please ask.
And here is the test class:
@RunWith(PowerMockRunner.class)
@PrepareForTest(XYZClass.class)
public class XYZClassTest {
private InitialContext ctx;
@Before
public void setUp() throws Exception {
PowerMockito.mockStatic(XYZClass.class);
ctx = Mockito.spy(new InitialContext());
PowerMockito.doReturn(ctx).when(XYZClass.class, "getCtx");
IMFTPManagerBean service1 = new IMFTPManagerBean();
Mockito.doReturn(service1).when(ctx).lookup(Mockito.eq("abc"));
}
@Test
public void testGetIMFTPManagerFacade() {
IMFTPManagerService service = XYZClass.getIMFTPManagerFacade();
assertEquals(IMFTPManagerService.class, service.getClass());
}
}
When you partially mock static methods of a class, you need to explicitely state if real implementation should be called (check thenCallRealMethod
below).
If you don't that, any method you call would be treated as a method on a mock without specified behaviour, and thus return null.
On top of that:
EJBFacades
which was not posted in the question. I've rewritten the test in terms of XYZClass
package com.test.powermock.teststacitejb;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import javax.naming.InitialContext;
import static org.junit.Assert.assertTrue;
@RunWith(PowerMockRunner.class)
@PrepareForTest(XYZClass.class)
public class XYZClassTest {
private InitialContext ctx;
@Before
public void setUp() throws Exception {
PowerMockito.mockStatic(XYZClass.class);
ctx = Mockito.spy(new InitialContext());
PowerMockito.doReturn(ctx).when(XYZClass.class, "getCtx");
IMFTPManagerBean service1 = new IMFTPManagerBean();
Mockito.doReturn(service1).when(ctx).lookup(Mockito.eq("abc"));
PowerMockito.when(XYZClass.getIMFTPManagerFacade()).thenCallRealMethod();
}
@Test
public void testGetIMFTPManagerFacade() {
IMFTPManagerService service = XYZClass.getIMFTPManagerFacade();
assertTrue(service instanceof IMFTPManagerService);
}
}