IAm*_*aja 11 java unit-testing mocking mockito
所以我被要求为我们的开发团队阅读模拟和BDD,并玩嘲笑,以便改进我们现有的一些单元测试(作为实验).
我最终选择与Mockito一起出于多种原因(有些原因超出了我的控制范围),但是因为它支持对模拟不适合的实例进行存根和模拟.
我整天都在学习Mockito,嘲笑(一般)和BDD.现在我准备深入挖掘并开始增强我们的单元测试.
所以我们有一个叫做WebAdaptor
有一个run()
方法的类:
public class WebAdaptor {
private Subscriber subscriber;
public void run() {
subscriber = new Subscriber();
subscriber.init();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意:我没有办法修改此代码(出于此问题范围之外的原因!).因此,我无法为其添加setter方法Subscriber
,因此它可以被认为是我内部无法访问的"黑盒子" WebAdaptor
.
我想编写一个包含Mockito
模拟的单元测试,并使用该模拟来调用verify
执行的WebAdaptor::run()
原因Subscriber::init()
.
所以这就是我到目前为止(内部WebAdaptorUnitTest
):
@Test
public void runShouldInvokeSubscriberInit() {
// Given
Subscriber mockSubscriber = mock(Subscriber.class);
WebAdaptor adaptor = new WebAdaptor();
// When
adaptor.run();
// Then
verify(mockSubscriber).init();
}
Run Code Online (Sandbox Code Playgroud)
当我运行这个测试,实际的Subscriber::init()
方法被执行(我可以从控制台输出告诉我的本地系统上生成的文件看到),没有的mockSubscriber
,这不应该做(或退货)任何东西.
我已经检查并重新检查:init
是public
,既不是static
或final
,并返回void
.根据文档,Mockito应该没有问题嘲笑这个对象.
所以它让我思考:我是否需要明确地将其mockSubscriber
与adaptor
?如果是这种情况,那么通常情况下,以下情况通常会解决它:
adaptor.setSubscriber(mockSubscriber);
Run Code Online (Sandbox Code Playgroud)
但由于我不能添加任何这样的二传手(请阅读我上面的注释),我不知道如何强迫这样的关联.所以,有几个非常密切相关的问题:
WebAdaptor
,我的处置是否有任何规避?提前致谢!
Dav*_*d V 10
您需要将模拟注入您正在测试的类中.您无需访问Subscriber.mockito和其他模拟框架的帮助方式是您不需要访问与之交互的对象.但是,您需要一种方法将模拟对象放入您正在测试的类中.
public class WebAdaptor {
public WebAdaptor(Subscriber subscriber) { /* Added a new constructor */
this.subscriber = subscriber;
}
private Subscriber subscriber;
public void run() {
subscriber.init();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以在模拟上验证您的交互,而不是在真实对象上.
@Test
public void runShouldInvokeSubscriberInit() {
// Given
Subscriber mockSubscriber = mock(Subscriber.class);
WebAdaptor adaptor = new WebAdaptor(mockSubscriber); // Use the new constructor
// When
adaptor.run();
// Then
verify(mockSubscriber).init();
}
Run Code Online (Sandbox Code Playgroud)
如果将订阅服务器添加到构造函数不是正确的方法,您还可以考虑使用工厂允许WebAdaptor从您控制的工厂实例化新的订阅服务器对象.然后,您可以模拟工厂提供模拟订阅服务器.
如果您不想更改生产代码并仍然能够模拟Subscriber类的功能,那么您应该查看PowerMock.它与Mockito一起工作正常,并允许您模拟新对象的创建.
Subscriber mockSubscriber = mock(Subscriber.class);
whenNew(Subscriber.class).withNoArguments().thenReturn(mockSubscriber);
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅PowerMock框架的文档.