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

Mocked method is returning null instead of expected object

我有如下源代码。

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") 方法。所以我用下面的方式做到了。我在模拟中没有收到任何错误或任何异常。此外,当我调试行个别方法 return 值时,getCtx() 方法是 returning 模拟对象,lookup() 方法也是 returning 所需的模拟对象目的。但是在完成整行 return (IMFTPManagerService) getCtx().lookup("abc"); 的执行后,return 行对测试 class 方法无效。任何人都可以找到我的解决方案吗?如果我的问题不清楚,请追问。

这是测试 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());
    }
}

当您部分模拟 class 的静态方法时,您需要明确说明是否应调用真正的实现(检查下面的 thenCallRealMethod)。

如果不这样做,您调用的任何方法都将被视为没有指定行为的模拟方法,因此 return null。

最重要的是:

  • 您使用的 EJBFacades 未在问题中发布。我已经根据 XYZClass
  • 重写了测试
  • 您的断言将失败,因为您是 return 服务的子class。
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);
    }
}