我正在尝试模拟一个 SOAP 拦截器类,其中一个类方法返回一个迭代器对象。但是,在仔细检查语法后,迭代器不会替换为真正的迭代器,并且 Mockito 在没有真实迭代器的情况下继续运行该方法。
我尝试使用各种 mockito 方法模拟拦截器的返回值(doReturn,当...然后返回),并且这两种方法都不起作用。我不确定我的嘲笑错误在哪里。
以下是我在测试类中模拟当前对象的方式:
@Mock private WebServiceTemplate template;
@Mock private SoapInterceptor interceptor;
@Mock private Iterator<Attachment> iterator;
@Test
public void testGetDocsSoapClient() {
@SuppressWarnings("unchecked")
Iterator<Attachment> realIterator = new ArrayListIterator();
ObjectFactory realFactory = new ObjectFactory();
assertFalse(realIterator.hasNext());
doReturn(realFactory.createAwsGetDocsRequest(createMockAwsGetDocsReq()))
.when(factory).createAwsGetDocsRequest(any (AwsGetDocsRequest.class));
doReturn(realFactory.createAwsGetDocsResponse(createAwsGetDocsResponse()))
.when(template).marshalSendAndReceive(any(Object.class), any(SoapActionCallback.class));
doReturn(realIterator)
.when(interceptor).getSoapAttachments();
下面是在实数类中调用该方法的方式。
Iterator<Attachment> soapAttachments = attachmentInterceptor.getSoapAttachments();
ImageListDVO imgList = convertToImageList(soapAttachments);
。我的测试用例在此私有方法的最后一行失败。
private ImageListDVO convertToImageList(Iterator<Attachment> attachments) {
ImageListDVO imgList = new ImageListDVO();
while(attachments.hasNext()) {
我应该正确地模拟对象,但我得到一个 NullPointerException,这表明对象没有被正确模拟或注入。
我认为您使用了错误的语法。如果我理解正确,您需要模拟具有方法getSoapAttachments()
的SoapInterceptor
为此,您需要将代码更改为如下所示的内容:
@InjectMocks
// the class under test should be put here
@Mock
SoapInterceptor attachmentInterceptor;
@Test
public void testGetDocsSoapClient() {
// this is either a real interceptor or a mocked version of it
Iterator<Attachment> iterator = ... ;
when(attachmentInterceptor.getSoapAttachments()).thenReturn(iterator);
}
do 方法通常在要模拟 void 方法时使用。
您还写道您已经尝试过此操作,因此您可能没有正确初始化 Mockito。
确保使用正确的 Runner/Extension/Rule 或其他任何内容(如 MockitoAnnotations.initMocks(testClass))。您可能正在使用的 JUnit 版本之间存在某些差异。(如果您仍然需要帮助,请提供您正在使用的JUnit & Mockito Verison)。
(见 https://static.javadoc.io/org.mockito/mockito-core/2.28.2/org/mockito/Mockito.html#9)
没有注入东西的另一种可能性可能是你的类的结构是 mockito 无法处理的。
从您的测试用例中,我假设您使用了字段注入,因此@Mock注释字段的名称应与您在测试类中拥有的private
字段相同。所以我再一次不确定是哪一个,因为你没有提供名字。
您正在使用的此类应该有适当的@InjectMocks注释,除非您手动提供模拟。(但在这种情况下,您可能不使用@Mock注释)。
编辑:
对你的问题的另一种解释可能是你正在尝试测试SoapInterceptor本身的方法,你想用其他东西替换返回迭代器的方法。
在这种情况下,您应该改为研究Spy
的创建,您的代码应如下所示:
@Test
public void testGetDocsSoapClient() {
SoapInterceptor interceptor = new SoapInterceptor();
SoapInterceptor spy = Mockito.spy(interceptor);
when(spy.getSoapAttachments()).thenReturn(iterator);
...
}