【发布时间】:2011-12-22 19:30:36
【问题描述】:
因此,我被要求为我们的开发团队阅读有关 mocking 和 BDD 的内容,并使用 mocks 来改进我们现有的一些单元测试(作为实验)。
我最终选择使用 Mockito 的原因有很多(其中一些超出了我的控制范围),但就是因为它同时支持存根和模拟,以便在不适合模拟的情况下使用。
我整天都在学习 Mockito、mock(一般)和 BDD。现在我已准备好深入研究并开始扩充我们的单元测试。
所以我们有一个名为WebAdaptor 的类,它有一个run() 方法:
public class WebAdaptor {
private Subscriber subscriber;
public void run() {
subscriber = new Subscriber();
subscriber.init();
}
}
请注意:我无法修改此代码(出于此问题范围之外的原因!)。因此,我确实没有能够为Subscriber 添加一个setter 方法,因此它可以被认为是我的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();
}
当我运行这个测试时,实际的 Subscriber::init() 方法被执行(我可以从控制台输出和本地系统上生成的文件中看出),不是mockSubscriber,它不应该做(或返回)任何事情。
我已经检查并重新检查:init 是public,既不是static 也不是final,它返回void。根据文档,Mockito 模拟这个对象应该没有问题。
所以我开始思考:我是否需要明确地将mockSubscriber 与adaptor 关联起来?如果是这种情况,那么通常情况下,以下通常会解决它:
adaptor.setSubscriber(mockSubscriber);
但由于我无法添加任何这样的设置器(请阅读我上面的注释),我不知道如何强制这样的关联。所以,几个非常密切相关的问题:
- 谁能确认我已正确设置测试(使用 Mockito API)?
- 我对失踪二传手的怀疑是否正确? (我需要通过 setter 关联这些对象吗?)
- 如果我的上述怀疑属实,并且我无法修改
WebAdaptor,我是否有任何规避措施?
提前致谢!
【问题讨论】:
-
这并不能直接回答您的问题,但 JMockIt 使这种黑盒模拟非常容易。 JMockIt 适合您吗?
-
如何在这个类中实例化订阅者?是否可以覆盖实例化代码以返回您控制的实例?
-
run() 是唯一使用订阅服务器的方法,因此无论如何它应该是该方法内的局部变量。同样,我无法更改代码...
标签: java unit-testing mocking mockito