我被要求为我们的开发团队学习模拟和BDD并尝试使用模拟来改进我们现有的一些单元测试(作为实验)。
最终我选择了Mockito,原因有几个(其中一些超出了我能控制的范围),但主要是因为它支持存根和模拟,以处理不适合进行模拟的情况。
我花了一整天的时间学习Mockito,模拟(总体而言)和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);
但由于我无法添加任何这样的setter(请阅读我上面的注释),因此我不知道如何强制进行这样的关联。因此,有几个非常相关的问题:
- 是否有人可以确认我是否已经正确设置了测试(使用Mockito API)?
- 我的对于缺失setter的怀疑是否正确?(我需要通过setter关联这些对象吗?)
- 如果我上面的怀疑是真的,并且我不能修改
WebAdaptor
,那么是否有任何绕过方法?
提前感谢!