模拟会话值

时间:2013-10-01 12:58:18

标签: java junit mocking mockito powermock

我试图模拟一个以递归方式在另一个方法中调用的方法。

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"));

    }

}

这里我从**返回Context.current()获取NullPointerException。getHttpSession()。getAttribute(value)** line。我认为它要我模拟从Context到.getAttribute的每个类。我怎样才能让它发挥作用?

2 个答案:

答案 0 :(得分: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"));
    }
}

答案 1 :(得分:0)

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

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

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

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

  

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