java - 在 Mockito 中模拟迭代器类时遇到问题
问题描述
我正在尝试模拟一个 SOAP Interceptor 类,其中一个类方法返回一个 Iterator 对象。但是,在仔细检查语法后,迭代器并没有被真正的迭代器替换,Mockito 继续运行没有真正迭代器的方法。
我尝试使用各种模拟方法(doReturn,when...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,这表明该对象没有被模拟或正确注入。
解决方案
我认为您使用了错误的语法。如果我理解正确,您需要模拟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);
}
当您想模拟 void 方法时,通常使用 do 方法。
您还写道您已经尝试过这个,因此您可能没有正确初始化 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
您在测试类中的字段具有相同的名称。因此,我再次不确定哪一个是您没有提供名称的。
除非您手动提供 Mocks,否则您正在使用的此类应该有一个适当的 @InjectMocks 注释。(但在这种情况下,您可能不会使用 @Mock 注释)。
编辑:
您的问题的另一种解释可能是您正在尝试测试 SoapInterceptor 本身的方法,并且您想用其他方法替换返回 Iterator 的方法。
在这种情况下,您应该研究创建 aSpy
而不是,您的代码应如下所示:
@Test
public void testGetDocsSoapClient() {
SoapInterceptor interceptor = new SoapInterceptor();
SoapInterceptor spy = Mockito.spy(interceptor);
when(spy.getSoapAttachments()).thenReturn(iterator);
...
}
推荐阅读
- c# - 统一挤压立方体
- r - 如何在 R 中使用 group_by 和汇总进行行求和
- azure - 使用 Azure 函数导出 CSV
- python - 视图 shop.views.product_list 没有返回 HttpResponse 对象。它返回 None 而不是
- javascript - 从 onclick 函数传递值并使用 javascript 复制该值
- python - 结帐和订单表的数据库设计
- python - python中的INVALID文字没有被删除
- c++ - 为什么需要链接库?
- c# - 用于从字符串中选择数字模式的正则表达式
- enums - 在 Julia 中将枚举转换为符号