我正在使用Mockito来测试我的课程。我正在尝试使用Deep存根,因为我没有在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");
}
}
}
现在我正在尝试对MyService类的create()方法进行单元测试。 我为SomeHelper注入了一个模拟如下
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
SomeHelper somehelper;
我现在想要的是在调用somehelper对象时调用invokeMeth()方法,在这种情况下它调用真实方法。
when(somehelper.invokeMeth(isA(RequestObject.class)))
.thenCallRealMethod();
我希望在这种情况下webServiceTemplate不为null。
但是当代码尝试执行行
时,我得到一个Nullpointer异常webServiceTemplate.marshalSendAndReceive(t);
任何线索我如何能够访问一个深度模拟对象(即在mock中进行模拟 - 在这种情况下是someserper mock中的webserviceTemplete模拟)然后应用when条件来抛出WebserviceIOException? 我希望这样,以便我可以测试MyService.create(),以便在向代码抛出WebServiceIOException时检查它是否正常运行。
答案 0 :(得分:3)
是的,当然,你正在混合真实对象和模拟。另外使用thenCallRealMethod
lloks就像部分模拟一样,这里感觉不对,这也就是javadoc of this method对此的讨论也就不足为奇了。
我明确应该强调你,而不是设计明智,有一个模拟返回模拟通常是一种气味。更准确地说,您正在违反得墨忒耳法,或者不遵循告诉,不要求原则。
任何查看代码我都不知道为什么代码需要模拟WebServiceTemplate
。您想要对MyService
进行单元测试,但我看不到与WebServiceTemplate
的关系。相反,你应该专注于与你帮助的互动。单独测试SomeHelper
,您可以检查SomeHelper
和WebServiceTemplate
之间的互动。
以下是我如何看待这件事的一个小例子:
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));
}
那些寻找真实用例的方法?
希望有所帮助