模拟方法返回null而不是预期的对象

时间:2019-09-04 06:24:05

标签: java unit-testing junit mockito powermockito

我有如下的源代码。

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;
        }
    }
}

我正在尝试为getIMFTPManagerFacade()方法编写测试用例。我需要模拟getCtx()方法,该方法既是私有的又是静态的,也是lookup("abc")方法。所以我以下面的方式做到了。我在模拟过程中没有收到任何错误或任何异常。同样,当我调试行个别方法的返回值时,getCtx()方法将返回模拟对象,而lookup()方法也将返回所需的模拟对象。但是在完成整个行return (IMFTPManagerService) getCtx().lookup("abc");的执行之后,该行向测试类方法返回null。谁能找到我的解决方案?如果我的问题不清楚,请询问。

这是测试类:

 @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());
    }
}

1 个答案:

答案 0 :(得分:0)

当部分模拟类的静态方法时,需要明确声明是否应调用真实的实现(请参见下面的thenCallRealMethod)。

如果不这样做,则您调用的任何方法都将被视为没有指定行为的模拟方法,从而返回null。

最重要的是:

  • 您使用的EJBFacades不在问题中。我已经根据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);
    }
}