1

我正在尝试模拟一个在另一个方法中递归调用的方法。

public class ABC
{
    public static Object getSessionAttribute(String value) {
        return Context.current().getHttpSession().getAttribute(value);
    }

    public static String myMethod(String xyz) throws Exception{

        /*Some important business logic*/

        String abc = getSessionAttribute("abcdefghj").toString();

        /*Some important business logic*/

        return abc;
    }

}

我的测试课是这样的;

@RunWith(PowerMockRunner.class)
@PrepareForTest(ABC.class)
public class ABCTest {

@Before
public void setUp() throws Exception {

  PowerMockito.mockStatic(ABC.class, Mockito.CALLS_REAL_METHODS);
  PowerMockito.when(ABC.getSessionAttribute("dummyValue")).thenReturn("myReturnValue");

}

    @Test
    public void testmyMethod() throws Exception {

        Assert.assertEquals("anyValue", ABC.myMethod("value"));

    }

}

在这里,我从 ** return Context.current().getHttpSession().getAttribute(value)** 行得到一个 NullPointerException。我认为它希望我模拟从 Context 到 .getAttribute 的每个类。我怎样才能让它工作?

4

2 回答 2

2

注意:我对 powermock 一无所知,但我使用过其他模拟工具。

您的代码的问题在于它与Context.current().getHttpSession()

如果您Context.current().getHttpSession()HttpSession接口替换并使类方法非静态,则可以像这样轻松地模拟和测试

public class ABC
{
    HttpSession session;
    public ABC(HttpSession session) {
        this.session = session;
    }

    private Object getSessionAttribute(String value) {
        return this.session.getAttribute(value);
    }

    public String myMethod(String xyz) throws Exception{

        /*Some important business logic*/

        String abc = getSessionAttribute("dummyValue").toString();

        /*Some important business logic*/

        return abc;
    }

}

@RunWith(PowerMockRunner.class)
@PrepareForTest(ABC.class)
public class ABCTest {
    HttpSession sessionMock;

    @Before
    public void setUp() throws Exception {
      sessionMock = ... create a mock that implements the interface HttpSession
      PowerMockito
                 .when(sessionMock.getSessionAttribute("dummyValue"))
                 .thenReturn("myReturnValue");
    }

    @Test
    public void testmyMethod() throws Exception {
        ABC sut = new ABC(sessionMock);
        Assert.assertEquals("anyValue", sut.myMethod("value"));
    }
}
于 2013-10-01T14:54:42.557 回答
0

你能在你的代码中分享你的导入吗?我可以为您模拟 Context 对象,但我不确定它属于哪个 JAR。

以下代码被认为是 Java 火车残骸,它使单元测试更加痛苦。

return Context.current().getHttpSession().getAttribute(value);

我建议通过提取局部变量来重构上面的代码。Martin Fowlwer 的建议也在这里

“Mockist 测试人员确实更多地谈论避免'火车残骸' - getThis().getThat().getTheOther() 风格的方法链。避免方法链也被称为遵循得墨忒耳法则。虽然方法链是一种气味,中间人对象因转发方法而臃肿的相反问题也是一种气味。”

于 2013-11-11T12:24:34.340 回答