使用Mockito我想模拟一个类的属性,以便我可以验证输出
public class MyClass extends ThirdPartyFramework {
Output goesHere;
@Override
protected setup(){
goesHere = new Output();
}
//...
}
public abstract class ThirdPartyFramework {
protected setup(){...}
//...
}
我需要注入一个Output类的模拟,这样我就可以验证我的代码是否写了正确的输出。
但我不能只@InjectMock
,因为调用了setup()
方法
运行中期并覆盖我的注射。
我不能在MyClass
中公开设置,因为我正在使用测试代码
with是通用的,需要适用于所有子类
ThirdPartyFramework
,因此我只提及ThirdPartyFramework
,意味着setup()
受到保护。
答案 0 :(得分:1)
你是否参加了Mockito?我问,因为Mockito FAQ Mockito FAQ声明它不支持模拟静态方法,我想在这种情况下你需要设置方法来创建模拟而不是真正的输出。
我已经将PowerMock用于类似的场景:
whenNew(NewInstanceClass.class).withArguments(any()).thenReturn(mockObject);
表示每次创建NewInstanceClass时都会返回我的mockObject,无论使用什么构造函数参数以及谁在什么时候构造NewInstanceClass。
在PowerMock文档中,我还发现了以下示例:
PowerMock.expectNew(NewInstanceClass.class).andReturn(mockObject)
实际上你可以使用它,即使你被Mockito绑定,PowerMock contains helpers for Mockito也可以解决这个问题,让你可以使用Mockito进行所有测试,而PowerMock可以模拟构建对象。像这样:
whenNew(Output.class).withNoArguments().thenReturn(yourOutputMock);
答案 1 :(得分:1)
我最终通过包装ThirdPartyFramework
并将该类放在与ThirdPartyFramework
类相同的包中来解决此问题。
这样我可以用Mockito模拟受保护的方法。然后我能够使用@InjectMock
注入Output
对象的模拟,并通过该模拟控制其方法调用。
答案 2 :(得分:0)
如何为“goHere”添加一个setter,然后进行setup()检查,如果为null,则只更改goHere的值。这样,您可以在测试中注入一个不会被覆盖的值。类似的东西:
protected void setGoesHere( Output output ){
goesHere = output;
}
@Override
protected void setup(){
if(goesHere != null) goesHere = new Output();
}
希望这有帮助。