莫皮托 - 深存根



我正在使用Mockito来测试我的课程。我正在尝试使用深度存根,因为我没有办法在 Mockito 中的另一个模拟对象中注入模拟。

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");
        }
    }
}

现在我正在尝试对 MyService 类的 create() 方法进行单元测试。我为SomeHelper注入了一个模拟,如下所示

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

我现在想要的是当 invokeMeth() 方法在模拟的某个助手对象上被调用时,在这种情况下它调用了真正的方法。

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

我期望在这种情况下网络服务模板不为空。

但是,当代码尝试执行该行时,我收到 Nullpointer 异常

webServiceTemplate.marshalSendAndReceive(t);

任何线索我可以访问一个深度模拟对象(即模拟中的模拟 - 在这种情况下,webserviceTemplete 模拟在某个助手模拟中),然后应用 when 条件来抛出 WebserviceIOException?我想要这个,以便我可以测试 MyService.create() 以检查它在 WebServiceIOException 被抛出代码时的行为是否正确。

是的,当然,您正在混合真实对象和模拟。另外,使用thenCallRealMethod lloks就像部分模拟一样,在这里感觉不对,难怪这种方法的javadoc也谈到了这一点。

我肯定应该强调你,设计明智,有一个模拟返回一个模拟通常是一种气味。更准确地说,你违反了得墨忒耳定律,或者没有遵循"告诉,不问"原则。

任何看你的代码,我不知道为什么代码需要嘲笑WebServiceTemplate.你想MyService单元测试,我看不出和WebServiceTemplate有什么关系。相反,您应该只关注与助手的交互。单元测试SomeHelper单独进行,您可以在其中检查SomeHelperWebServiceTemplate之间的交互。

以下是我如何看待这件事的一个小例子:

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));
}

那些如何寻找您的真实用例?

希望有帮助

相关内容

  • 没有找到相关文章

最新更新