Mockito无法模拟此类:接口

时间:2018-11-08 13:48:51

标签: java-8 mockito powermock powermockito

mockito和powermock出现问题,我可以使用最终的静态方法模拟抽象类而没有问题。当尝试像WebIServerSession那样模拟接口时,我得到下面的stacktrace。我已经看过powermock github存储库中的其他问题,它似乎与jvm版本有关。我已经升级到https://github.com/mockito/mockito/issues/636中所述的最新的1.8 Java版本,并且仍然遇到相同的错误。可能与Powermock与Mockito 2的兼容性有关吗?

import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.verifyPrivate;
import static org.powermock.api.mockito.PowerMockito.whenNew;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;

@BeforeMethod
public void setup() throws Exception {
    mockStatic(ResourceBundle.class);
    mockStatic(WebObjectsFactory.class);
    WebObjectsFactory webObjectsFactory = mock(WebObjectsFactory.class);
    WebIServerSession webIServerSession = mock(WebIServerSession.class);

    PowerMockito.when(WebObjectsFactory.getInstance()).thenReturn(webObjectsFactory);
    PowerMockito.when(webObjectsFactory.getIServerSession()).thenReturn(webIServerSession);
    whenNew(ThreadLocal.class).withNoArguments().thenReturn(errorContainer);

    MockitoAnnotations.initMocks(this);
}


@Test
public void shouldBeTrue() {
    assertTrue(true);
}

Maven依赖项:

<dependencies>
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>6.14.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>2.8.9</version>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-core</artifactId>
        <version>1.7.4</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-testng</artifactId>
        <version>1.7.4</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito2</artifactId>
        <version>1.7.4</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-reflect</artifactId>
        <version>1.7.4</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Stacktrace:

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: interface com.microstrategy.web.objects.WebIServerSession.

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.191-b12
JVM name           : Java HotSpot(TM) 64-Bit Server VM
JVM version        : 1.8.0_191-b12
JVM info           : mixed mode
OS name            : Mac OS X
OS version         : 10.14.1


Underlying exception : java.lang.IllegalArgumentException: Could not create type

    at com.myproject.SSOESMTest.setup(SSOESMTest.java:63)
    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:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
    at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:59)
    at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:458)
    at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:222)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:523)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
    at org.testng.TestRunner.privateRun(TestRunner.java:648)
    at org.testng.TestRunner.run(TestRunner.java:505)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
    at org.testng.SuiteRunner.run(SuiteRunner.java:364)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
    at org.testng.TestNG.runSuites(TestNG.java:1049)
    at org.testng.TestNG.run(TestNG.java:1017)
    at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Caused by: java.lang.IllegalArgumentException: Could not create type
    at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:154)
    at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:365)
    at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:174)
    at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:376)
    at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClass(TypeCachingBytecodeGenerator.java:32)
    at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMockType(SubclassByteBuddyMockMaker.java:71)
    at org.mockito.internal.creation.bytebuddy.SubclassByteBuddyMockMaker.createMock(SubclassByteBuddyMockMaker.java:42)
    at org.powermock.api.mockito.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:50)
    at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMethodInvocationControl(DefaultMockCreator.java:116)
    at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMock(DefaultMockCreator.java:69)
    at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.mock(DefaultMockCreator.java:46)
    at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:138)
    ... 28 more
Caused by: java.lang.NoClassDefFoundError: com/microstrategy/utils/xml/SAXSupport
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
    at java.lang.Class.getDeclaredMethods(Class.java:1975)
    at net.bytebuddy.description.method.MethodList$ForLoadedMethods.<init>(MethodList.java:109)
    at net.bytebuddy.description.type.TypeDescription$ForLoadedType.getDeclaredMethods(TypeDescription.java:8426)
    at net.bytebuddy.description.type.TypeDescription$Generic$OfNonGenericType.getDeclaredMethods(TypeDescription.java:3654)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.doAnalyze(MethodGraph.java:634)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.analyze(MethodGraph.java:596)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.doAnalyze(MethodGraph.java:632)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.analyze(MethodGraph.java:596)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.doAnalyze(MethodGraph.java:632)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.analyze(MethodGraph.java:596)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.doAnalyze(MethodGraph.java:632)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.compile(MethodGraph.java:567)
    at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$AbstractBase.compile(MethodGraph.java:465)
    at net.bytebuddy.dynamic.scaffold.MethodRegistry$Default.prepare(MethodRegistry.java:463)
    at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:198)
    at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:189)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3394)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:3583)
    at org.mockito.internal.creation.bytebuddy.SubclassBytecodeGenerator.mockClass(SubclassBytecodeGenerator.java:94)
    at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$1.call(TypeCachingBytecodeGenerator.java:37)
    at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$1.call(TypeCachingBytecodeGenerator.java:34)
    at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:152)
    ... 39 more
Caused by: java.lang.ClassNotFoundException: com.microstrategy.utils.xml.SAXSupport
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:202)
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass1(DeferSupportingClassLoader.java:89)
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:79)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 63 more


Test ignored.

===============================================
Default Suite
Total tests run: 1, Failures: 0, Skips: 1
Configuration Failures: 1, Skips: 2
===============================================


Process finished with exit code 0

7 个答案:

答案 0 :(得分:5)

由于所使用的Mockito版本,最有可能发生此异常。

尝试使用以下依赖项替换当前版本的嘲笑核心。

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>2.22.0</version>
    <scope>test</scope>
</dependency>

忽略pom.xml中覆盖托管版本的警告

答案 1 :(得分:1)

在尝试模拟非公共接口时,我也遇到了此问题,并且错误消息没有意义,因为在模拟同一接口时,我在另一个套件中的所有测试均正确通过。

就我而言,我不得不降级Mockito Core库并再次还原它以使其正常运行。这是我采取的步骤:

  1. 在模块级别build.gradle文件条目中找到Mockito Core依赖项:
    testImplementation 'org.mockito:mockito-core:2.25.0'
  1. 降级到另一个有效版本,在我的示例2.23.0中:
    testImplementation 'org.mockito:mockito-core:2.23.0'
  1. 进行Gradle同步并等待完成
  2. 将Mockito Core依赖项还原到以前(或更新)的版本:
    testImplementation 'org.mockito:mockito-core:2.25.0'
  1. 再次同步项目
  2. 再次运行测试

答案 2 :(得分:0)

添加

@RunWith(MockitoJUnitRunner.class)

答案 3 :(得分:0)

像这样注释您的测试班

@RunWith(PowerMockRunner.class)
@PrepareForTest({ResourceBundle.class, WebObjectsFactory.class, AnyOtherClassThatContainsStaticMethod.class, . . .})

ref:https://github.com/powermock/powermock/wiki/mockstatic

答案 4 :(得分:0)

确保您的界面可见性是公开的。

我不确定这是否是您的解决方案。在Android Studio中进行测试时,我遇到了同样的问题。

我的解决方案是用

替换core-mockito
androidTestImplementation "org.mockito:mockito-android:2.25.0"

然后它开始完美运行。

对于那些正在测试Android Studio并遇到相同问题的人来说,这可能是一个解决方案。

答案 5 :(得分:0)

我有一个类似的问题。我惊讶地拥有:

Mockito cannot mock this class: interface javax.servlet.ServletContext.

这只是当我在IDE(IntelliJ Idea)中运行测试时。如果我尝试通过maven命令运行它-它通过了。 为了使测试在IntelliJ Idea中起作用,我只是更改了配置: 将Shorten command line设置为JAR manifest

答案 6 :(得分:0)

这很奇怪,但在 build.gradle 文件中添加以下行后,它对我有用

original no ms display 2354 ms
original with ms display 3545 ms
new with ms display 1221 ms
newest with ms display 691 ms