【问题标题】:Mockito cannot mock this classMockito 无法模拟此类
【发布时间】:2017-04-24 07:39:16
【问题描述】:

我正在尝试模拟一个公共课程,但是这样做时,Mockito 会引发 Mockito cannot mock this class 异常。

我想模拟的班级:https://github.com/scribejava/scribejava/blob/master/scribejava-core/src/main/java/com/github/scribejava/core/builder/ServiceBuilder.java

测试代码:

package xyz.jacobclark.adapter;

import com.github.scribejava.apis.TwitterApi;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.OAuth1RequestToken;
import com.github.scribejava.core.oauth.OAuth10aService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.io.IOException;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.IsInstanceOf.any;

@RunWith(MockitoJUnitRunner.class)
public class TwitterOAuthAdapterTest {
    @Mock
    ServiceBuilder serviceBuilder;

    @Test
    public void getRequestTokenShouldReturnAValidRequestToken() throws IOException {
        class TwitterOAuthAdapter {
            private final OAuth10aService service;

            public TwitterOAuthAdapter(ServiceBuilder serviceBuilder){
                this.service = serviceBuilder
                    .apiKey("")
                    .apiSecret("")
                    .build(TwitterApi.instance());
            }

            public OAuth1RequestToken getRequestToken() throws IOException {
                return this.service.getRequestToken();
            }
        }

        TwitterOAuthAdapter oAuthAdapter = new TwitterOAuthAdapter(serviceBuilder);
        Assert.assertThat(oAuthAdapter.getRequestToken(), is(any(OAuth1RequestToken.class)));
    }
}

完整的堆栈跟踪:

xyz.jacobclark.adapter.TwitterOAuthAdapterTest

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class com.github.scribejava.core.builder.ServiceBuilder.

Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.


Java               : 1.8
JVM vendor name    : Oracle Corporation
JVM vendor version : 25.0-b70
JVM name           : Java HotSpot(TM) 64-Bit Server VM
JVM version        : 1.8.0-b132
JVM info           : mixed mode
OS name            : Mac OS X
OS version         : 10.11.3


Underlying exception : java.lang.IllegalArgumentException: object is not an instance of declaring class

    at org.mockito.internal.runners.SilentJUnitRunner$1.withBefores(SilentJUnitRunner.java:29)
    at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:276)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.SilentJUnitRunner.run(SilentJUnitRunner.java:39)
    at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
    at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:103)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at net.bytebuddy.description.type.TypeDescription$Generic$AnnotationReader$ForTypeArgument.resolve(TypeDescription.java:3843)
    at net.bytebuddy.description.type.TypeDescription$Generic$AnnotationReader$Delegator$Chained.resolve(TypeDescription.java:3468)
    at net.bytebuddy.description.type.TypeDescription$Generic$AnnotationReader$ForTypeArgument.resolve(TypeDescription.java:3803)
    at net.bytebuddy.description.type.TypeDescription$Generic$AnnotationReader$Delegator.asList(TypeDescription.java:3439)
    at net.bytebuddy.description.type.TypeDescription$Generic$OfWildcardType$ForLoadedType.getDeclaredAnnotations(TypeDescription.java:4748)
    at net.bytebuddy.description.type.TypeDescription$Generic$Visitor$TypeVariableErasing.onWildcard(TypeDescription.java:680)
    at net.bytebuddy.description.type.TypeDescription$Generic$Visitor$TypeVariableErasing.onWildcard(TypeDescription.java:663)
    at net.bytebuddy.description.type.TypeDescription$Generic$OfWildcardType.accept(TypeDescription.java:4656)
    at net.bytebuddy.description.type.TypeDescription$Generic$Visitor$TypeVariableErasing.onParameterizedType(TypeDescription.java:691)
    at net.bytebuddy.description.type.TypeDescription$Generic$Visitor$TypeVariableErasing.onParameterizedType(TypeDescription.java:663)
    at net.bytebuddy.description.type.TypeDescription$Generic$OfParameterizedType.accept(TypeDescription.java:4998)
    at net.bytebuddy.description.type.TypeList$Generic$AbstractBase.accept(TypeList.java:249)
    at net.bytebuddy.description.type.TypeDescription$Generic$Visitor$TypeVariableErasing$RetainedTypeVariable.getUpperBounds(TypeDescription.java:832)
    at net.bytebuddy.description.type.TypeDescription$Generic$OfTypeVariable.asErasure(TypeDescription.java:5373)
    at net.bytebuddy.description.method.MethodDescription$AbstractBase.asTypeToken(MethodDescription.java:701)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default$Key$Harmonized.of(MethodGraph.java:881)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default$Key$Store.registerTopLevel(MethodGraph.java:1074)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.doAnalyze(MethodGraph.java:588)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.analyze(MethodGraph.java:548)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.analyzeNullable(MethodGraph.java:567)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.doAnalyze(MethodGraph.java:581)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.compile(MethodGraph.java:521)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$AbstractBase.compile(MethodGraph.java:442)
    at net.bytebuddy.dynamic.scaffold.MethodRegistry$Default.prepare(MethodRegistry.java:480)
    at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:160)
    at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:153)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:2568)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:2670)
    at org.mockito.internal.creation.bytebuddy.SubclassBytecodeGenerator.mockClass(SubclassBytecodeGenerator.java:84)
    at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$CachedBytecodeGenerator.getOrGenerateMockClass(TypeCachingBytecodeGenerator.java:91)
    at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClass(TypeCachingBytecodeGenerator.java:38)
    at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMockType(SubclassByteBuddyMockMaker.java:67)
    at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMock(SubclassByteBuddyMockMaker.java:38)
    at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createMock(ByteBuddyMockMaker.java:26)
    at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35)
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:63)
    at org.mockito.Mockito.mock(Mockito.java:1637)
    at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:33)
    at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:16)
    at org.mockito.internal.configuration.DefaultAnnotationEngine.createMockFor(DefaultAnnotationEngine.java:39)
    at org.mockito.internal.configuration.DefaultAnnotationEngine.process(DefaultAnnotationEngine.java:63)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:59)
    at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:43)
    at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:67)
    ... 23 more


Test ignored.
Process finished with exit code 255

【问题讨论】:

标签: java unit-testing mockito


【解决方案1】:

尽管它没有具体回答问题(问题是 Java 8),但我还是通过 Google 来到这里的。使用 Java 11,我通过在 build.gradle 中包含以下依赖项解决了这个问题:

compile group: 'org.mockito', name: 'mockito-core', version: '2.22.0'

如讨论here

【讨论】:

【解决方案2】:

这是因为 Java/Mockito 兼容性。例如,如果您将 Java 11 与 Mockito 2.17.0 一起使用,则会引发相同的错误(升级到 Mockito 2.22.0 或更高版本将解决此问题)。除了深入研究他们的release artifact on Github,我还没有看到一份详细说明兼容性矩阵的综合文档。这是一个有用的兼容性矩阵(基于快速测试)

  • Mockito * - 2.17.0 => Java 8

(脚注:* - 不知道有多远)

  • Mockito 2.18.0 - 3.2.4 => Java 11

【讨论】:

    【解决方案3】:

    有同样的问题。当我将我的 Java JDK 版本更新到 1.8.0_131 时,错误消失了。

    【讨论】:

      【解决方案4】:

      我遇到了同样的问题。 我尝试了堆栈溢出中列出的所有内容,即

      • 更新的 JDK 版本
      • 更新了 Maven
      • 让 ByteBuddy 和 Mockito 使用兼容的版本。
      • 清除缓存
      • 使用最新的 mockito 版本等

      还有这个:https://github.com/mockito/mockito/issues/1606.

      但对我没有任何帮助。

      我清除了所有缓存,然后重新安装了 Android Studio 解决了这个问题。

      可能只是清除 Android Studio 使用的所有缓存也可以解决它。

      【讨论】:

      • github问题的链接修复了错误,谢谢!
      【解决方案5】:

      我遇到了同样的问题。

      我的 jdk 版本是11.0.4+10-LTS

      我用org.springframework.boot:spring-boot-starter-parent:2.0.7.RELEASE

      我将 Mockito 升级到 3.3.0

      异常仍然发生。

      然后我这样做了:

      1. 从 spring-boot-starter-test 中排除 mockito-core

      2. 在 pom 文件中添加以下内容

             <dependency>
                  <groupId>org.mockito</groupId>
                  <artifactId>mockito-core</artifactId>
                  <version>3.3.0</version>
                  <scope>test</scope>
                  <exclusions>
                      <exclusion>
                          <groupId>net.bytebuddy</groupId>
                          <artifactId>byte-buddy</artifactId>
                      </exclusion>
                      <exclusion>
                          <groupId>net.bytebuddy</groupId>
                          <artifactId>byte-buddy-agent</artifactId>
                      </exclusion>
                  </exclusions>
              </dependency>
              <dependency>
                  <groupId>net.bytebuddy</groupId>
                  <artifactId>byte-buddy</artifactId>
                  <version>1.10.5</version>
                  <scope>test</scope>
              </dependency>
              <dependency>
                  <groupId>net.bytebuddy</groupId>
                  <artifactId>byte-buddy-agent</artifactId>
                  <version>1.10.5</version>
                  <scope>test</scope>
              </dependency>
      

      【讨论】:

      • 经过数小时的寻找解决方案后,这是让它发挥作用的方法。谢谢!
      【解决方案6】:

      当我检查我的 Java-8 项目的依赖关系树时,我发现 spring-boot-starter-test 使用的是 Mockito 2.15.0。通过排除传递 Mockito 依赖项并使用 2.23.4 版本显式重新添加它(如果没有自动完成则重新构建)来修复。我的 Maven POM 的片段:

      <dependencies>
      ...
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
          <exclusions>
              <exclusion>
                  <groupId>org.mockito</groupId>
                  <artifactId>mockito-core</artifactId>
              </exclusion>
          </exclusions>
      </dependency>
      
      <dependency>
          <groupId>org.mockito</groupId>
          <artifactId>mockito-core</artifactId>
          <version>2.23.4</version>
      </dependency>
      </dependencies>
      

      如果使用 gradle,它看起来像:

      dependencies {
          ...
          def withoutMockito = {
              exclude group: 'org.mockito', module: 'mockito-core'
          }
          testImplementation "org.springframework.boot:spring-boot-starter-test:2.0.2-RELEASE", withoutMockito
          testImplementation "org.mockito:mockito-core:2.23.4"
       }
      

      【讨论】:

        【解决方案7】:

        文件 -> 使缓存无效/重新启动

        我的课程是公开的,不是最终的。这成功了。

        【讨论】:

          【解决方案8】:

          对我来说,问题是类必须是open

          我正在使用:

          @Mock lateinit var mock: ClassUnderTest

          模拟的方法。

          【讨论】:

          • 在我想模拟的模块信息中添加带有 open 标记的类包后为我工作
          【解决方案9】:

          确保在运行 junit 时通过 Run As -> Run Configuration -> JRE 选项卡正确选择 jdk 版本。

          【讨论】:

            【解决方案10】:

            对我来说,添加此依赖项解决了问题

            androidTestImplementation "org.mockito:mockito-android:${versions.mockito}"
            

            【讨论】:

              【解决方案11】:

              使用 OpenJ9 JVM 更新到新的 Java 版本后,我遇到了同样的问题,现在我使用的是 HotSpot JVM。我没有这个问题了

              【讨论】:

                【解决方案12】:

                更新JDK,当我将JDK 1.8更改为11时修复了错误,我也添加了这个

                @Rule
                 public MockitoRule rule = MockitoJUnit.rule();
                

                这是关于“告诉 Mockito 根据 @Mock 注释创建模拟”

                【讨论】:

                  【解决方案13】:

                  当我从 JDK 13 降级到 1.8 时,我遇到了同样的问题,错误消失了。我认为 Mockito 版本与版本 13 不兼容。

                  【讨论】:

                    【解决方案14】:

                    我在我的 Android Studio 中遇到了同样的问题。

                    刚刚将org.mockito:mockito-core2.18.3 升级到2.19.0(截至目前最新)解决了我的问题。

                    【讨论】:

                      【解决方案15】:

                      在 android studio 中我遇到了这个错误,我清理了项目并重新启动了 IDE 来修复它。

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 2021-01-27
                        • 1970-01-01
                        • 2020-05-23
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多