如何使用MOCKITO对同一类的私有方法返回值



我使用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)

测试方法1()时,测试控制器触发isValidUser(userObj.getSessionID())时,我想从isValidUser()方法返回true,以便我可以继续测试其余的实现逻辑。

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

使用powermockito

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

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

使用whitebox

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

使用Mockito.s

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

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

另一个答案是:修复您的 design ,而不是转向大型PowerMock Hammer。

是的,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();
}

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

最新更新