我使用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将完成这项工作...在某个时候为奇异的失败做好准备,这可能需要几个小时才能追捕;
没有在生产代码中找到真正的错误。因此,考虑一个替代方案:
- 请勿使用静态方法调用。如果周围有一些静态方法,您将无法触摸;考虑围绕它构建一个小界面。
- 而是:使用依赖项注入,并简单地将实现某些接口的对象传递到您的生产代码中。因为您可以在没有的情况下模拟此类对象> 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();
}
希望这会有所帮助。快乐编码!