【问题标题】:Mockito Exception - when() requires an argument which has to be a method call on a mockMockito 异常 - when() 需要一个参数,该参数必须是模拟上的方法调用
【发布时间】:2012-02-29 11:48:08
【问题描述】:

我有一个使用 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)

我尝试了不同的方法,但不断收到此错误消息。我正在使用带有 Mockito 的 Spring 3.1.0.RELEASE。请分享并指导我正确的方向。

【问题讨论】:

  • 我有同样的问题,但我正在使用:@Autowired @ReplaceWithMock(beanName="logDao") private LogDao logDaoMock;

标签: java controller mockito spring-test


【解决方案1】:

您需要先创建一个 pcUserService 的 MOCK,然后使用该模拟。

PcUserService mock = org.mockito.Mockito.mock(PcUserService.class);
when(mock.read("1")).thenReturn(pcUser);

【讨论】:

  • 但在这种情况下我无法调试。它真的调用了那个方法吗?
  • @eatSleepCode:在这个例子中,REAL 方法PcUserService.read 永远不会被调用。相反,一个 Mockito Mock 被调用,这个模拟返回 pcUser
  • 是的,我遇到了这个问题,我有一个服务,比如说TestService,它有一个方法testMethod()testMethod 中的代码包括调用另一个服务方法,例如。 AnotherTestService.getData()。所以在我的情况下,我无法模拟 AnotherTestService 我该怎么办?
  • 为什么不能用模拟替换AnotherTestService
  • @eatSleepCode:也许你应该看看这个答案:stackoverflow.com/a/20856647/280244
【解决方案2】:

如果其他人遇到这个问题......

您尝试模拟的方法pcUserService.read 也可能被声明为final 方法。据我所知,这似乎会导致 Mockito 出现问题。

【讨论】:

  • 诊断没问题,但有什么解决办法:p
  • @amdev 不要将pcUserService.read 设为final :) 我知道这并不理想,但您无能为力。 Mockito 无法模拟最终方法。有关更多详细信息和可能的解决方法,请参阅stackoverflow.com/questions/3793791/final-method-mocking
  • 实际上,有时您不会模拟自己的类,而是模拟来自外部依赖项的某个类。但没关系,我找到了如何使用 mockito stackoverflow.com/questions/14292863/… 模拟最终方法
【解决方案3】:

此问题的另一个解决方案可能是,如果测试类使用PowerMockRunner,您可能必须在@PrepareForTest 注释中将要模拟的类添加到列表中。

例如-

@PrepareForTest({ PcUserService.class })

【讨论】:

  • 谢谢,我以为我有,但我实际上将接口添加到@preparefortest 列表,而不是类,这个答案让我在那里仔细检查。
【解决方案4】:

这种错误还有另一个可能的原因 - 有时 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 包中的“何时”在编译级别与 org.mockito.Mockito.any() 兼容,但在运行时失败并显示完全相同的错误消息。

【讨论】:

    【解决方案5】:

    如果你使用Kotlin,你应该知道方法默认是final。所以写open fun而不是fun。感谢@djkelly99 的提示。

    【讨论】:

    【解决方案6】:

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

    【讨论】:

      【解决方案7】:

      为了帮助遇到同样问题的其他人;

      您尝试模拟的方法 pcUserService.read 被声明为 final 方法。静态方法似乎会导致 Mockito 出现问题。

      【讨论】:

        【解决方案8】:

        基本上,您需要使用 PowerMockito.mockStatic 为类的所有静态方法启用静态模拟。这意味着可以使用 when-thenReturn 语法对它们进行存根。 例如: PowerMockito.mockStatic(TestClass.class); when(TestClass.getString()).thenReturn("HelloWorld!"); 注意:您必须将@PrepareForTest({ TestClass.class }) 添加到您的单元测试类中。

        【讨论】:

          【解决方案9】:

          在我的情况下,它是通过注入 @MockBean 解决的。

          例如

          @MockBean
          StateRepository mockStateRepository;
          

          【讨论】:

            【解决方案10】:

            如果您使用 KOIN,请在 gradle 的依赖项中包含:

            dependencies {
                ...
                testImplementation "org.koin:koin-test:2.0.0"
            }
            

            【讨论】:

              【解决方案11】:

              在模拟另一个类的静态方法时,我在测试 someClass 的方法时遇到了类似的问题。在这种情况下,我们需要添加 @PrepareForTest({anotherClass.class, someClass.class}) 具有静态方法的类和调用者类。

              【讨论】:

                【解决方案12】:

                如果您在使用MockedStaticMockito.mockStatic 时遇到此异常,也可能意味着您在调用静态方法时混合了匹配器和文字。

                尝试将YourClass.staticMethod(any(), "literal") 等任何组合更改为YourClass.staticMethod(any(), eq("literal"))

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-05-08
                  • 2020-05-12
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多