Mockito:Mocking" Blackbox"依赖 [英] Mockito: Mocking "Blackbox" Dependencies

查看:173
本文介绍了Mockito:Mocking" Blackbox"依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我被要求为我们的开发团队阅读模拟和BDD,并玩嘲笑,以便改进我们现有的一些单元测试(作为实验)。

So I have been asked to read up on mocking and BDD for our development team and play around with mocks so as to improve a handful of our existing unit tests (as an experiment).

我最终选择和Mockito一起出于多种原因(有些原因超出了我的控制范围),但是因为它在模拟不合适时支持实例的存根和模拟。

I have ultimately chosen to go with Mockito for a number of reasons (some outside the scope of my control), but namely because it supports both stubbing and mocking for instances when mocking would not be appropriate.

我花了一整天时间学习Mockito,嘲笑(一般)和BDD。现在我准备深入挖掘并开始扩充单元测试。

I have spent all day learning about Mockito, mocking (in general) and BDD. And now I am ready to dig in and start augmenting our unit tests.

所以我们有一个名为 WebAdaptor 的类它有一个 run()方法:

So we have a class called WebAdaptor that has a run() method:

public class WebAdaptor {

    private Subscriber subscriber;

    public void run() {

        subscriber = new Subscriber();
        subscriber.init();
    }
}

请注意:我没有办法修改此代码(出于此问题范围之外的原因!)。因此我能够为 Subscriber 添加setter方法,因此它可以被认为是一个无法访问的黑盒子我的 WebAdaptor

Please note: I do not have a way to modify this code (for reasons outside the scope of this question!). Thus I do not have the ability to add a setter method for Subscriber, and thus it can be thought of as an unreachable "blackbox" inside of my WebAdaptor.

我想写一个包含 Mockito的单元测试 mock,并使用该模拟到验证执行 WebAdaptor :: run()导致要调用的Subscriber :: init()

I want to write a unit test which incorporates a Mockito mock, and uses that mock to verify that executing WebAdaptor::run() causes Subscriber::init() to be called.

所以这就是我到目前为止的内容(在<$ c内) $ c> WebAdaptorUnitTest ):

So here's what I've got so far (inside WebAdaptorUnitTest):

@Test
public void runShouldInvokeSubscriberInit() {

    // Given
    Subscriber mockSubscriber = mock(Subscriber.class);
    WebAdaptor adaptor = new WebAdaptor();

    // When
    adaptor.run();

    // Then
    verify(mockSubscriber).init();
}

当我运行此测试时,实际的订阅者: :init()方法被执行(我可以从控制台输出中看到并看到在我的本地系统上生成的文件), mockSubscriber ,不应该做(或返回)任何事情。

When I run this test, the actual Subscriber::init() method gets executed (I can tell from the console output and seeing files being generated on my local system), not the mockSubscriber, which shouldn't do (or return) anything.

我已经检查并重新检查: init public ,既不是 static final ,它返回 void 。根据文档,Mockito应该没有问题嘲笑这个对象。

I have checked and re-checked: init is public, is neither static or final, and it returns void. According to the docs, Mockito should have no problem mocking this object.

所以它让我思考:我是否需要明确地关联 mockSubscriber 使用适配器?如果是这种情况,那么通常情况下,以下情况通常会解决它:

So it got me thinking: do I need to explictly associate the mockSubscriber with the adaptor? If this is a case, then ordinarily, the following would normally fix it:

adaptor.setSubscriber(mockSubscriber);

但由于我不能添加任何这样的二传手(请阅读我上面的注释),我在关于如何强迫这种关联的损失。所以,有几个非常密切相关的问题:

But since I cannot add any such setter (please read my note above), I'm at a loss as to how I could force such an association. So, several very-closely-related questions:


  • 任何人都可以确认我已经正确设置了测试(使用Mockito API) ?

  • 我怀疑失踪的二传手是否正确? (我是否需要通过setter关联这些对象?)

  • 如果我的怀疑是真的,我无法修改 WebAdaptor ,我的处置是否存在任何规避?

  • Can anyone confirm that I've set the test up correctly (using the Mockito API)?
  • Is my suspicion about the missing setter correct? (Do I need to associate these objects via a setter?)
  • If my above suspicion is true, and I can't modify WebAdaptor, are there any circumventions at my dispose?

提前致谢!

推荐答案

您需要将模拟注入您正在测试的类中。您无需访问Subscriber。 mockito和其他模拟框架的帮助方式是您不需要访问与之交互的对象。但是你需要一种方法将模拟对象放入你正在测试的类中。

You need to inject the mock into the class which you are testing. You do not need access to Subscriber. The way mockito and other mocking frameworks help is that you do not need access to objects which you are interacting with. You do however need a way to get mock objects into the class you are testing.

public class WebAdaptor {

    public WebAdaptor(Subscriber subscriber) { /* Added a new constructor */
       this.subscriber = subscriber;
    }

    private Subscriber subscriber;

    public void run() {
        subscriber.init();
    }
}

现在你可以验证你在模拟上的互动了,而不是

Now you can verify your interactions on the mock, rather than on the real object.

@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从您控制的工厂实例化新的Subscriber对象。然后,您可以模拟工厂提供模拟订阅者。

If adding the Subscriber to the constructor is not the correct approach, you could also consider using a factory to allow WebAdaptor to instantiate new Subscriber objects from a factory which you control. You could then mock the factory to provider mock Subscribers.

这篇关于Mockito:Mocking&quot; Blackbox&quot;依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆