我有一个非常简单的测试用例,它使用的是Mockito和Spring Test框架。当我这样做时
when(pcUserService.read("1")).thenReturn(pcUser);
我得到这个例外。
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
at com.project.cleaner.controller.test.PcUserControllerTest.shouldGetPcUser(PcUserControllerTest.java:93)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
我已经尝试了不同的方法,但不断收到此错误消息。我正在使用Spring 3.1.0.RELEASE和Mockito。请分享并引导我朝着正确的方向前进。
您需要先创建一个 pcUserService 的 MOCK,然后使用该模拟。
PcUserService mock = org.mockito.Mockito.mock(PcUserService.class);
when(mock.read("1")).thenReturn(pcUser);
万一其他人遇到这个问题....
也可能是您尝试模拟的方法pcUserService.read
被声明为final
方法。 据我所知,这似乎会导致 Mockito 出现问题。
如果你使用 Kotlin
,你应该知道默认情况下final
方法。所以写open fun
而不是fun
.感谢@djkelly99的小费。
的另一种解决方案可能是,在使用 PowerMockRunner
的测试类的情况下,您可能必须在@PrepareForTest
注释中添加要模拟的类到列表中。
例如-
@PrepareForTest({ PcUserService.class })
在我的情况下,它是通过注入@MockBean
来解决的。
例如。
@MockBean
StateRepository mockStateRepository;
这种错误还有另一个可能的原因 - 有时IDE更喜欢从另一个包静态导入Mockito.when((:
import static io.codearte.catchexception.shade.mockito.Mockito.when;
与
import static org.mockito.Mockito.when; //should normally use this one
问题是io.codearte包中的"when"在编译级别上与org.mockito.Mockito.any((兼容,但在运行时失败并显示完全相同的错误消息。
我遇到了同样的问题,我试图模拟它的方法是最终方法。我删除了修饰符,它工作正常。
如果在使用 MockedStatic
或 Mockito.mockStatic
时遇到此异常,这也可能意味着您在调用静态方法时混合了匹配器和文本。
尝试将任何混音(如 YourClass.staticMethod(any(), "literal")
(更改为YourClass.staticMethod(any(), eq("literal"))
为了其他遇到相同问题的人的帮助;
您尝试模拟的方法 pcUserService.read 被声明为最终方法。静态方法似乎会导致 Mockito 出现问题。
基本上,您需要使用 PowerMockito.mockStatic 为类的所有静态方法启用静态模拟。这意味着可以使用 when-thenReturn 语法来存根它们。例如: PowerMockito.mockStatic(TestClass.class);
when(TestClass.getString()).thenReturn("HelloWorld!");
注意:您必须将@PrepareForTest({ TestClass.class })
添加到单元测试类中。
如果您使用 KOIN,请包含在 gradle 的依赖项中:
dependencies {
...
testImplementation "org.koin:koin-test:2.0.0"
}
我在模拟另一个类的静态方法时遇到了类似的问题,该方法在内部测试某个类的方法。在这种情况下,我们需要添加@PrepareForTest({otherClass.class,someClass.class}(具有静态方法和调用者类的类。
当我遇到此异常时,我在需要注入@Mock对象的类上使用@InjectMocks(通过构造函数注入(。
经过多次搜索,我终于偶然发现了这篇文章:
https://mkyong.com/spring-boot/mockito-when-requires-an-argument-which-has-to-be-a-method-call-on-a-mock/
要从中获取的关键部分是(来自文章(:
当Mockito看到这个@InjectMocks时,它并没有嘲笑它,它只是创建一个普通实例,因此 when(( 将失败。
所以这使我收到此异常消息
when(( 需要一个参数,该参数必须是"模拟方法调用"。
现在有意义;你不是在实际模拟中使用,而是在实际实例上使用。
该链接还提供了问题的解决方案:
要解决它,请注释@Spy以部分模拟它。
在@InjectMocks上面,放@Spy。
作为旁注,如果您尝试通过将@Mock放在@InjectMocks之上来使其成为模拟,您将获得异常:
org.mockito.exceptions.base.MockitoException:这种组合不允许在单个字段上使用注释:@Mock 和 @InjectMocks
在@InjectMocks之上使用@Spy为我解决了这个问题。
我遇到了同样的问题,这是因为模拟对象被定义为@Bean
,并且由于缺少 spring 属性值,测试中的覆盖@Bean
@Bean
@Primary
public JwtTokenUtil jwtTokenUtil() {
return Mockito.mock(JwtTokenUtil.class);
}
@Autowired
private JwtTokenUtil jwtTokenUtil;
when(jwtTokenUtil.validateToken(jwtToken)).thenReturn(true);
修复
在应用程序测试属性中spring.main.allow-bean-definition-overriding=true
如果上述任何内容回答了您的情况,请检查您是否错过了测试方法的@Test
注释。
@Test
public void my_test_method(){
}
只是引用,因为这是我的情况。 只是错过了注释。