如何使用mockito为同一类的私有方法返回值

时间:2016-12-28 04:44:47

标签: java unit-testing junit mockito powermockito

我正在开发基于Spring的项目,我正在使用JUnit + Mockito编写单元测试用例。我将布尔值存入同一测试类的私有方法时遇到问题(在将访问级别更改为public之后,我也无法存根布尔值)。

Bellow显示了同一问题代码的模拟

class ABC {

public String method1(User userObj){

   String result = "";

    if(!isValidUser(userObj.getSessionID())){

        return "InvalidUser";

    } esle{

       // execute some logic

    }


return result;

}


private boolean isValidUser(String sessionId) {

  // Hear it call some other class to validate the user 

    if (sessionId == null || UserSessionPool.getInstance().getSessionUser(sessionId) == null) {
        return false;
    } else {
        return true;
    }
}

}

听到我想为method1()编写测试用例,在ABC类我有一个名为isValidUser()的方法,它有助于通过查看包含所有已登录已使用详细信息的全局会话池来识别会话中的用户即UserSessionPool.getInstance().getSessionUser(sessionId)

在测试method1()时,时刻测试控制器触发isValidUser(userObj.getSessionID())我希望从true方法返回isValidUser(),以便我可以继续测试实现逻辑的休息。

到目前为止,我已尝试使用间谍和模拟对象的方法来调用isValidUser()方法并尝试返回true但没有任何效果。

使用PowerMockito

PowerMockito.doNothing().when(spyed_ABC_ClassObject,"isValidUser",true);

PowerMockito.doReturn(true).when(cntrl, "isValidUser", Mockito.anyString());

使用白盒

Whitebox.invokeMethod(spyed_ABC_ClassObject, "isValidUser", Mockito.anyString());

使用Mockito.when

when(spyed_ABC_ClassObject.isValidUser(Mockito.anyString())).thenReturn(true);

Mockito.doNothing().when(spyed_ABC_ClassObject).isValidUser(Mockito.anyString());

2 个答案:

答案 0 :(得分:4)

另一个答案是:修复你的设计而不是转向大型PowerMock锤子。

是的,PowerMock允许您模拟静态方法。但你应该明白: static 在良好的OO设计中是异常。只有在有充分理由的情况下才能使用它。因为它导致你的类之间的紧密耦合,并且令人惊讶:它打破你编写合理的单元测试的能力。是的,PowerMock有效;但有时,它没有。当你的课程成长,并且你“静态地”做更多的事情时,因为,你知道,PowerMock会做这个工作......准备好在某些时候出现奇怪的失败,这可能需要几个小时来追捕;没有在生产代码中找到真正的错误。

所以,考虑一个替代方案:

  1. 不要使用静态方法调用。如果有一些静态的方法,你无法触摸;考虑围绕它构建一个小型界面。
  2. 相反:使用依赖注入并简单地将实现某个接口的对象传递到您的生产代码中。因为你可以模拟这样的对象而不需要对PowerMock(ito)的需求。
  3. 从这个意义上讲:您只是创建了难以测试代码。现在,您打算使用PowerMock解决这个问题。另一种方式(在我看来更合理)是学习如何编写可测试的代码。 Here是一个很好的起点。

答案 1 :(得分:1)

你可以试一试。

@Before
public void setUp() {
    UserSessionPool mockConnectionPool = Mockito.mock(UserSessionPool.class);
}

@Test
public void testName() throws Exception {
    //given
    PowerMockito.mockStatic(UserSessionPool.class);
    BDDMockito.given(UserSessionPool.getInstance()(...)).willReturn(mockConnectionPool);
    Mockito.when(mockConnectionPool.getSessionUser(Mockito.anylong())).thenReturn(something);


    //then
    PowerMockito.verifyStatic();

}

希望这会有所帮助。快乐的编码!