因此,我被要求为我们的开发团队阅读嘲弄和BDD的内容,并使用模拟来改进我们现有的一些单元测试(作为一个实验)。
我最终选择使用Mockito的原因有很多(有些原因超出了我的控制范围),但也就是因为它支持在不适合嘲弄的情况下使用Mockito。
我一整天都在学习Mockito,嘲弄(一般)和BDD。现在,我准备深入研究并开始增强我们的单元测试。
因此,我们有一个名为WebAdaptor的类,它有一个run()方法:
public class WebAdaptor {
private Subscriber subscriber;
public void run() {
subscriber = new Subscriber();
subscriber.init();
}
}请注意:我没有办法修改这段代码(原因超出了这个问题的范围!)因此,我没有能力为Subscriber添加一个setter方法,因此可以认为它是在我的WebAdaptor中不可访问的“黑盒”。
我想编写一个单元测试,它合并了一个Mockito模拟,并将这个模拟用于执行WebAdaptor::run()导致调用Subscriber::init()的verify。
下面是我到目前为止(在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);但是,由于我不能添加任何这样的设置(请阅读我上面的笔记),我不知道如何才能强制这样一个协会。因此,有几个非常密切相关的问题:
WebAdaptor,我有什么规避措施吗?提前感谢!
发布于 2011-12-22 19:44:39
您需要将模拟注入正在测试的类中。您不需要访问订阅服务器。mockito和其他模拟框架的帮助之处在于,您不需要访问正在与其交互的对象。但是,您确实需要一种方法来将模拟对象导入您正在测试的类中。
public class WebAdaptor {
public WebAdaptor(Subscriber subscriber) { /* Added a new constructor */
this.subscriber = subscriber;
}
private Subscriber subscriber;
public void run() {
subscriber.init();
}
}现在,您可以在模拟上而不是在实际对象上验证您的交互。
@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();
}如果向构造函数添加订阅服务器不是正确的方法,则还可以考虑使用工厂来允许WebAdaptor从您控制的工厂实例化新的订阅服务器对象。然后,可以将工厂模拟为提供者模拟订阅服务器。
发布于 2011-12-22 19:53:59
如果您不想更改生产代码,并且仍然能够模拟订阅者类的功能,那么您应该看看PowerMock。它与Mockito一起工作很好,并允许您模拟新对象的创建。
Subscriber mockSubscriber = mock(Subscriber.class);
whenNew(Subscriber.class).withNoArguments().thenReturn(mockSubscriber);进一步的细节将在PowerMock文档框架中解释。
发布于 2011-12-26 15:41:23
有一种方法可以将模拟注入到被测试的类中,而无需对代码进行任何修改。这可以使用Mockito WhiteBox来完成。这是一个非常好的特性,可以用来从测试中注入类的依赖项。下面是一个关于它如何工作的简单示例,
@Mock
Subscriber mockSubscriber;
WebAdaptor cut = new WebAdaptor();
@Before
public void setup(){
//sets the internal state of the field in the class under test even if it is private
MockitoAnnotations.initMocks(this);
//Now the whitebox functionality injects the dependent object - mockSubscriber
//into the object which depends on it - cut
Whitebox.setInternalState(cut, "subscriber", mockSubscriber);
}
@Test
public void runShouldInvokeSubscriberInit() {
cut.run();
verify(mockSubscriber).init();
}希望这会有所帮助:)
https://stackoverflow.com/questions/8608826
复制相似问题