我的功能如下。
public String getDecodedToken() throws UnsupportedEncodingException {
if (token == null) {
String token = ClassContainingStatic
.findString("static");
this.token = new String(Base64.decodeBase64(token), "UTF-8");
}
return token;
}
为了测试该函数,我不想模拟ClassContainingStatic类,因为它会使测试无效。相反,我希望看到如果调用发生在ClassContainingStatic.findString(" static")而不模拟对象。有没有办法实现对真实对象的函数调用次数?
答案 0 :(得分:1)
当然可以进行一些重构。如果您使用单独的方法提取对静态类的调用:
public String getDecodedToken() throws UnsupportedEncodingException{
if( token == null ){
token = createToken();
}
return token;
}
String createToken() throws UnsupportedEncodingException{
String token = ClassContainingStatic.findString("static");
return new String( Base64.decodeBase64(token), "UTF-8" );
}
现在你可以创建一个模拟或间谍,并简单地验证该方法是否被调用。
ClassUnderTest spy = Mockito.spy( new ClassUnderTest() );
String token = spy.getDecodedToken();
Mockito.verify( spy ).createToken();
我认为"static"
字符串是固定的。如果没有,请将其作为参数传递给createToken
课程,然后您可以相应地调整verify
。
我可能在Mockito语法中犯了一个错误,但一般的想法应该是清楚的。唯一的缺点是你需要创建一个可见/受保护的包(如果你想要的话,甚至是公共的,但通常情况并非如此),以便可以进行verify
调用。
答案 1 :(得分:1)
这里你需要的基本东西被称为Mockito语言的间谍。
虽然mock是一个全新的对象,但是spy会包装一个现有实例并默认将对其方法的调用转发给原始对象,同时支持模拟方法调用或验证调用。
但是你有另一个挑战:你要验证的方法似乎是一个静态方法。使用Mockito,您无法模拟静态方法。您有两个基本选项:
重构,以便该方法不再是静态的,并且您将提供该方法的对象作为构造函数的参数提供。此参数可以是模拟或间谍。
使用PowerMock模拟静态方法。我只接受在遗留项目中使用PowerMock,其中需要使用尽可能少的重构来创建测试。 PowerMock很笨拙,但很笨拙,很容易引起问题,例如:通过动态创建大量类来导致PermGen问题。