如何在 Java 中模拟单元测试的通用参数?
How to mock a generic parameter for a unit test in Java?
我有一个函数签名,我想模拟一个外部服务。
public <T> void save(T item, AnotherClass anotherClassObject);
鉴于此函数签名和 class 名称 IGenericService
如何使用 PowerMock 模拟它?
还是莫基托?
对于这个泛型,我使用:Class Theodore
作为 T item
中的 T。例如,我尝试使用:
doNothing().when(iGenericServiceMock.save(any(Theodore.class),
any(AnotherClass.class));
IntelliJ 曲柄这个:
save(T, AnotherClass) cannot be applied to
(org.Hamcrest.Matcher<Theodore>, org.Hamcrest.Matcher<AnotherClass>)
并引用了以下原因:
reason: No instance(s) of type variable T exist
so that Matcher<T> conforms to AnotherClass
首先,如果泛型参数处理得当,问题应该可以解决。在这种情况下,人们可以做些什么?
更新:正如 ETO 分享的那样:
doNothing().when(mockedObject).methodToMock(argMatcher);
命运相同。
尝试使用 Mockito 的 ArgumentMatcher
。同样在 when
中只放置模拟的参考:
doReturn(null).when(iGenericServiceMock).save(
ArgumentMatchers.<Theodore>any(), ArgumentMatchers.any(AnotherClass.class));
您向 when
传递了错误的参数。可能有点混乱,但是 when
方法有两种不同的用法(实际上这是两种不同的方法):
when(mockedObject.methodYouWantToMock(expectedParameter, orYourMatcher)).thenReturn(objectToReturn);
doReturn(objectToReturn).when(mockedObject).methodYouWantToMock(expectedParameter, orYourMatcher);
注:注意when
方法中两种情况下的输入参数.
在您的特定情况下,您可以这样做:
doReturn(null).when(iGenericServiceMock).save(any(Theodore.class), any(AnotherClass.class));
这将解决您的编译问题。然而,测试将在运行时失败并显示 org.mockito.exceptions.misusing.CannotStubVoidMethodWithReturnValue
,因为您正试图从 void
方法中 return 某些东西(null
不是 void
)。你应该做的是:
doNothing().when(iGenericServiceMock).save(any(Theodore.class), any(AnotherClass.class));
稍后您可以使用 verify
方法检查与模拟的交互。
更新:
检查您的导入。您应该使用 org.mockito.Matchers.any
而不是 org.hamcrest.Matchers.any
。
很好 swift 答案!我终于通过以下代码顺利解决了这个问题:
doNothing().when(iGenericServiceMock).save(Mockito.any(), Mockito.any());
直到我将 Mockito 添加到 any 方法之前,Intellij 才再次对它感到高兴。
我有一个函数签名,我想模拟一个外部服务。
public <T> void save(T item, AnotherClass anotherClassObject);
鉴于此函数签名和 class 名称 IGenericService
如何使用 PowerMock 模拟它?
还是莫基托?
对于这个泛型,我使用:Class Theodore
作为 T item
中的 T。例如,我尝试使用:
doNothing().when(iGenericServiceMock.save(any(Theodore.class),
any(AnotherClass.class));
IntelliJ 曲柄这个:
save(T, AnotherClass) cannot be applied to
(org.Hamcrest.Matcher<Theodore>, org.Hamcrest.Matcher<AnotherClass>)
并引用了以下原因:
reason: No instance(s) of type variable T exist
so that Matcher<T> conforms to AnotherClass
首先,如果泛型参数处理得当,问题应该可以解决。在这种情况下,人们可以做些什么?
更新:正如 ETO 分享的那样:
doNothing().when(mockedObject).methodToMock(argMatcher);
命运相同。
尝试使用 Mockito 的 ArgumentMatcher
。同样在 when
中只放置模拟的参考:
doReturn(null).when(iGenericServiceMock).save(
ArgumentMatchers.<Theodore>any(), ArgumentMatchers.any(AnotherClass.class));
您向 when
传递了错误的参数。可能有点混乱,但是 when
方法有两种不同的用法(实际上这是两种不同的方法):
when(mockedObject.methodYouWantToMock(expectedParameter, orYourMatcher)).thenReturn(objectToReturn);
doReturn(objectToReturn).when(mockedObject).methodYouWantToMock(expectedParameter, orYourMatcher);
注:注意when
方法中两种情况下的输入参数.
在您的特定情况下,您可以这样做:
doReturn(null).when(iGenericServiceMock).save(any(Theodore.class), any(AnotherClass.class));
这将解决您的编译问题。然而,测试将在运行时失败并显示 org.mockito.exceptions.misusing.CannotStubVoidMethodWithReturnValue
,因为您正试图从 void
方法中 return 某些东西(null
不是 void
)。你应该做的是:
doNothing().when(iGenericServiceMock).save(any(Theodore.class), any(AnotherClass.class));
稍后您可以使用 verify
方法检查与模拟的交互。
更新:
检查您的导入。您应该使用 org.mockito.Matchers.any
而不是 org.hamcrest.Matchers.any
。
很好 swift 答案!我终于通过以下代码顺利解决了这个问题:
doNothing().when(iGenericServiceMock).save(Mockito.any(), Mockito.any());
直到我将 Mockito 添加到 any 方法之前,Intellij 才再次对它感到高兴。