我正在尝试模拟SOAP Interceptor类,其中一种类方法返回Iterator对象。但是,在仔细检查语法之后,迭代器不会被真正的迭代器替换,并且Mockito会在没有真正的迭代器的情况下继续运行该方法。
我尝试使用各种模拟方法(doReturn,何时... thenReturn)来模拟拦截器的返回值,而这两种方法均无效。我不确定我的错误在哪里。
这是我在测试类中模拟当前对象的方式:
@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,它指示对象没有被正确模拟或注入。
答案 0 :(得分:0)
我认为您使用的是错误的语法。如果我理解正确,则需要模拟具有方法SoapInterceptor
getSoapAttachments()
为此,您需要将代码更改为以下内容:
@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)
另一个未注入的可能性是您的类以模仿无法处理的方式构造。
从您的测试用例中,我假设您使用了字段注入,因此@Mock注释字段应与测试类中的private
字段具有相同的名称。因此,我再次不确定您提供的姓名是哪一个。
除非您手动提供Mocks,否则您正在使用的此类应该有一个正确的@InjectMocks批注。 (但是在这种情况下,您可能将不使用@Mock注释)。
编辑:
对您问题的另一种解释可能是您正在尝试测试SoapInterceptor本身的方法,并且想要用其他方式替换返回Iterator的方法。
在这种情况下,您应该研究创建Spy
的情况,并且代码应如下所示:
@Test
public void testGetDocsSoapClient() {
SoapInterceptor interceptor = new SoapInterceptor();
SoapInterceptor spy = Mockito.spy(interceptor);
when(spy.getSoapAttachments()).thenReturn(iterator);
...
}