简体   繁体   English

Mockito - 深存根

[英]Mockito - deep stubbing

I am using Mockito to test my classes.我正在使用 Mockito 来测试我的课程。 I am trying to use Deep stubbing as I didn't a way on injecting a Mock inside another mock object in Mockito.我正在尝试使用 Deep stubbing,因为我没有办法在 Mockito 的另一个模拟对象中注入 Mock。

class MyService{

    @Resource
    SomeHelper somehelper;

    public void create()
    {
        //....
        somehelper.invokeMeth(t);
    }
}

class SomeHelper{
    @Resource
    private WebServiceTemplate webServiceTemplate;

    public void invokeMeth(T t)
    {
        try{
            //...
            webServiceTemplate.marshalSendAndReceive(t);
        }catch (final WebServiceIOException e) {
            throw new MyAppException("Service not running");
        }
    }
}

Now I am trying to Unit test the MyService class's create() method.现在我正在尝试对 MyService 类的 create() 方法进行单元测试。 I have injected a mock for SomeHelper as follows我已经为 SomeHelper 注入了一个模拟如下

@Mock(answer = Answers.RETURNS_DEEP_STUBS)
SomeHelper somehelper;

What I want now is when the invokeMeth() method gets called on the mocked somehelper object it calls the real method in this case.我现在想要的是当 invokeMeth() 方法在模拟的 somehelper 对象上被调用时,它会在这种情况下调用真正的方法。

when(somehelper.invokeMeth(isA(RequestObject.class)))
    .thenCallRealMethod();

I was expecting the webServiceTemplate not be null in this case.在这种情况下,我期望 webServiceTemplate 不为空。

However I get a Nullpointer exception when the code tries to execute the line但是,当代码尝试执行该行时,我收到 Nullpointer 异常

webServiceTemplate.marshalSendAndReceive(t);

Any clue how I can get access to a deep mock object (ie mock within a mock - in this case webserviceTemplete mock inside somehelper mock) and then apply a when condition to throw a WebserviceIOException ?有什么线索可以访问深度模拟对象(即模拟中的模拟 - 在这种情况下,一些帮助模拟中的 webserviceTemplete 模拟)然后应用 when 条件抛出 WebserviceIOException ? I want this so that I can test the MyService.create() to check it behaves properly when a WebServiceIOException is thrown down the code.我想要这个,以便我可以测试 MyService.create() 以检查它在代码中抛出 WebServiceIOException 时的行为是否正常。

Yes of course, you are mixing real objects and mocks.是的,当然,您正在混合真实对象和模拟。 Plus using the thenCallRealMethod lloks like a partial mock, it feels wrong here, it's no wonder the javadoc of this method talks about that as well.加上使用thenCallRealMethod lloks 就像一个部分模拟,这里感觉不对,难怪这个方法javadoc 也谈到了这一点。

I definatelty should stress you than, design wise, having a mock that returns a mock is often a smell.我肯定应该强调你,而不是设计明智,有一个返回一个模拟的模拟通常是一种气味。 More precisely you are breaking the Demeter Law , or not following the Tell, Don't Ask principle.更准确地说,您违反了得墨忒耳定律,或者不遵循告诉,不要问原则。

Any looking at your code I don't why the code would need to mock WebServiceTemplate .任何查看您的代码的人都不知道为什么代码需要模拟WebServiceTemplate You want to unit test MyService , and I don't see a relationship to WebServiceTemplate .您想对MyService进行单元测试,但我看不到与WebServiceTemplate的关系。 Instead you should focus on the interactions with you helper only.相反,您应该只关注与您的助手的互动。 And unit test SomeHelper separately where you'll be able to check the interactions between SomeHelper and WebServiceTemplate .分别SomeHelper单元测试,您可以在其中检查SomeHelperWebServiceTemplate之间的交互。

Here's a little example of how I see the thing:这是我如何看待这件事的一个小例子:

public void ensure_helper_is_used_to_invoke_a_RequestObject() {
  // given a service that has an helper collaborator
  ... other fixture if necessary

  // when
  myService.behaviorToTest();

  // then
  verify(someHelperMock).invokeMeth(isA(RequestObject.class));
}

How those that look for your real use case ?那些寻找你真正用例的人如何?

Hope that helps希望有帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM