Java Mockito 不能模拟这个类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41050029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:06:43  来源:igfitidea点击:

Mockito cannot mock this class

javaunit-testingmockito

提问by Jacob Clark

I am attempting to mock a public class, however when doing so, Mockito throws an Mockito cannot mock this classexception.

我试图模拟一个公共类,但是这样做时,Mockito 会引发Mockito cannot mock this class异常。

Class I wish to mock: https://github.com/scribejava/scribejava/blob/master/scribejava-core/src/main/java/com/github/scribejava/core/builder/ServiceBuilder.java

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

Test code:

测试代码:

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)));
    }
}

Full stacktrace:

完整的堆栈跟踪:

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.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.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access
@Rule
 public MockitoRule rule = MockitoJUnit.rule();
0(ParentRunner.java:58) at org.junit.runners.ParentRunner.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

回答by Andrushenko Alexander

Had same issue. When I updated my Java JDK version to 1.8.0_131 the error disappeared.

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

回答by nkadu1

I had the same issue. I tried everything that is listed on stack overflow i.e

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

  • updated JDK version
  • updated Maven
  • Made ByteBuddy and Mockito to use compatible versions.
  • cleared cache
  • use latest mockito versions etc
  • 更新了 JDK 版本
  • 更新的 Maven
  • 使 ByteBuddy 和 Mockito 使用兼容版本。
  • 清除缓存
  • 使用最新的 mockito 版本等

and this : https://github.com/mockito/mockito/issues/1606.

和这个:https: //github.com/mockito/mockito/issues/1606

But nothing worked for me.

但没有什么对我有用。

I cleared all the cache and then reinstalled Android studio which fixed the issue.

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

Probably just clearing all the caches that Android Studio uses could have solved it too.

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

回答by Aji

I had the same issue after I update to new java version with OpenJ9 JVM, now I am using HotSpot JVM. I don't have this issue anymore

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

回答by JoschJava

Even though it's not specifically answering the question (question is Java 8), I came here via Google. Using Java 11, I solved this issue by including the following dependency in build.gradle:

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

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

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

as discussed here

正如这里所讨论的

回答by Jason Hartley

File -> Invalidate Caches / Restart

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

enter image description here

在此处输入图片说明

My class was public and non-final. This did the trick.

我的课是公开课,非期末考试。这成功了。

回答by Lily Mo

Update JDK, the error fixed when I've changed JDk 1.8 to 11, also I added this

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

<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>

It's about 'Tells Mockito to create the mocks based on the @Mock annotation'

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

回答by itro

I had the same issue when I downgrade from JDK 13 to 1.8 error disappears. I think Mockito versions is not compatible with version 13.

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

回答by papigee

It is because of Java/Mockito compatibility. For example, if you are using Java 11 with Mockito 2.17.0, it will throw the same error (Upgrading to Mockito 2.22.0 or later will solve it). Aside from digging into their release artifact on Github, I am yet to see a comprehensive document that spells out the compatibility matrix. Here is a helpful compatibility Matrix (based on quick test)

这是因为 Java/Mockito 兼容性。例如,如果您在 Mockito 2.17.0 中使用 Java 11,它会抛出相同的错误(升级到 Mockito 2.22.0 或更高版本将解决它)。除了在 Github 上深入研究他们的发布工件之外,我还没有看到详细说明兼容性矩阵的文档。这是一个有用的兼容性矩阵(基于快速测试)

  • Mockito * - 2.17.0 => Java 8
  • Mockito * - 2.17.0 => Java 8

(footnote: * - dont know how far back)

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

  • Mockito 2.18.0 - 3.2.4 => Java 11
  • Mockito 2.18.0 - 3.2.4 => Java 11

回答by Adrian Redgers

When I examined my Java-8 project's dependency tree I found that spring-boot-starter-test was using Mockito 2.15.0. Fixed by excluding that transitive Mockito dependency and re-adding it explicitly with version 2.23.4 (and re-build if not done automatically). Snippet of my maven POM:

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

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"
 }

If using gradle it will look something like:

如果使用 gradle,它将类似于:

##代码##

回答by Cory Roy

For me the issue was that the classes needed to be open.

对我来说,问题是课程必须是open.

I am using the:

我正在使用:

@Mock lateinit var mock: ClassUnderTest

@Mock lateinit var mock: ClassUnderTest

method of mocking.

嘲讽的方法。