繁体   English   中英

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

[英]How to stub return value for the private method of same class using mockito

我正在研究基于 spring 的项目并使用 JUnit + Mockito 编写单元测试用例。 我在将布尔值存根到同一测试类的私有方法时遇到问题(在将访问级别更改为公共后,我仍然无法存根布尔值)。

下面的代码片段显示了相同问题的模拟

class ABC {

    public String method1(User userObj){
        String result = "";

        if(!isValidUser(userObj.getSessionID())){
            return "InvalidUser";
        } else {
           // execute some logic
        }

        return result;
    }


    private boolean isValidUser(String sessionId) {
        // Here it calls 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())我想从isValidUser()方法返回true ,以便我可以继续测试其余的实现逻辑。

到目前为止,我已经尝试使用 spy 和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());

另一个答案是:修复您的设计,而不是求助于 PowerMock 的大锤子。

是的,PowerMock 允许您模拟静态方法。 但是你应该明白:静态是好的 OO 设计中的一个异常 只有当你有很好的理由时才使用它。 因为它会导致您的类之间的紧密耦合,令人惊讶的是:它破坏了您编写合理单元测试的能力。 是的,PowerMock 有效; 但有时,事实并非如此。 当你的班级增长,你“静态地”做越来越多的事情,因为,你知道,PowerMock 会完成这项工作......在某些时候为奇怪的失败做好准备,这可能需要几个小时才能找到; 永远不会在您的生产代码中发现真正的错误。

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

  1. 不要使用静态方法调用。 如果周围有一些您无法触及的静态方法; 考虑围绕它构建一个小界面。
  2. 相反:使用依赖注入并简单地将实现某些接口的对象传递到您的生产代码中。 因为您可以在不需要 PowerMock(ito) 的情况下模拟此类对象。

从这个意义上说:您只是创建了难以测试的代码。 现在您打算使用 PowerMock 修复该问题。 另一种方式(在我看来更合理)是首先学习如何编写可测试的代码。 是一个很好的起点。

你能试试这个吗。

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

}

希望这可以帮助。 快乐编码!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM