代码之家  ›  专栏  ›  技术社区  ›  Marcos

Mockito无法模拟这个类:接口

  •  0
  • Marcos  · 技术社区  · 7 年前

    我对mockito和powermock有一个问题,我可以用最终的静态方法模拟一个抽象类,没有问题。当试图模仿界面时 WebIServerSession 我在下面找到了踪迹。我看过powermock github repo中的其他问题,它似乎与jvm版本有关。我已经升级到最新的1.8Java版本,如中所述 https://github.com/mockito/mockito/issues/636 我还是会犯同样的错误。这可能与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
    
    0 回复  |  直到 7 年前
        1
  •  10
  •   Keegs    5 年前

    由于所使用的Mockito版本,最有可能出现异常。

    尝试用以下依赖项替换mockito core的当前版本。

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

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

        2
  •  4
  •   Zoe - Save the data dump 张群峰    6 年前

    添加

    @RunWith(MockitoJUnitRunner.class)
    
        3
  •  4
  •   Farruh Habibullaev    6 年前

    确保你的界面是公开的。

    我不确定这是否能解决你的问题。我在Android Studio测试时也遇到了同样的问题。

    我的解决方案是用

    androidTestImplementation "org.mockito:mockito-android:2.25.0"
    

    然后它开始完美工作。

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

        4
  •  1
  •   Danny Meyer-Kristensen    6 年前

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

    在我的例子中,我不得不降低Mockito核心库的级别,并再次恢复它以使其工作。以下是我采取的步骤:

    1. 在模块级查找Mockito核心依赖项 build.gradle 文件条目:
        testImplementation 'org.mockito:mockito-core:2.25.0'
    
    1. 降级到另一个有效版本,在我的示例2.23.0中:
        testImplementation 'org.mockito:mockito-core:2.23.0'
    
    1. 进行梯度同步并等待完成
    2. 将Mockito Core依赖项恢复到以前的版本(或更新版本):
    测试实施组织。mockito:mockito核心:2.25.0'
    
    1. 再次同步项目
    2. 再次运行测试
        5
  •  0
  •   Dharman vijay    5 年前

    我也有类似的问题。我惊讶地发现:

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

    这是我在IDE(IntelliJ Idea)中运行测试的时候。如果我试图通过maven命令运行它,它就通过了。 为了在IntelliJ Idea中进行测试,我刚刚更改了配置: 设置 Shorten command line JAR manifest .

        6
  •  0
  •   Sushant Gosavi    5 年前

    这很奇怪,但在构建中添加了以下行之后。gradle归档对我有用吗

    androidTestImplementation "org.mockito:mockito-android:$mockitoAndroid"
    
        7
  •  -1
  •   Mansoor Ali Milan    6 年前

    像这样注释你的测试类

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

    裁判: https://github.com/powermock/powermock/wiki/mockstatic