Mockito Exception - when() 需要一个参数,该参数必须是模拟上的方法调用



我有一个非常简单的测试用例,它使用的是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((兼容,但在运行时失败并显示完全相同的错误消息。

我遇到了同样的问题,我试图模拟它的方法是最终方法。我删除了修饰符,它工作正常。

如果在使用 MockedStaticMockito.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(){
}

只是引用,因为这是我的情况。 只是错过了注释。

相关内容

  • 没有找到相关文章

最新更新