如何让 Powermock 与 Dexmaker 一起工作

How to get Powermock to work with Dexmaker

我正在尝试使用以下 build.gradle 配置将 Powermock 作为我的 Android 测试的依赖项:

dependencies{
    compile 'com.android.support:appcompat-v7:21.0.+'
    androidTestCompile('org.mockito:mockito-core:1.9.5')
    androidTestCompile('com.google.dexmaker:dexmaker:1.2')
    androidTestCompile('com.google.dexmaker:dexmaker-mockito:1.2')
    androidTestCompile('org.powermock:powermock-module-junit4:1.5.5') {
        exclude module: 'junit'
    }
    androidTestCompile('org.powermock:powermock-api-mockito:1.5.5') {
        exclude module: 'mockito-all'
    }
}

但是,编译器抱怨

Error:Gradle: Execution failed for task ':app:packageDebugTest'.
> Duplicate files copied in APK mockito-extensions/org.mockito.plugins.MockMaker
    File 1: ~/.gradle/caches/modules-2/files-2.1/com.google.dexmaker/dexmaker-mockito/1.2/b99884a4c6ef6335ba376f79aa79632b2421c17c/dexmaker-mockito-1.2.jar
    File 2: ~/.gradle/caches/modules-2/files-2.1/com.google.dexmaker/dexmaker-mockito/1.2/b99884a4c6ef6335ba376f79aa79632b2421c17c/dexmaker-mockito-1.2.jar

查看 jar 结构,我注意到 Dexmaker 和 Powermock 都在 mockito-extensions

中声明了一个 MockMaker

什么是 MockMaker?它们有何不同? 最重要的问题是:是否有可能让 Powermock 与 Dexmaker 很好地协同工作?

提前致谢。任何帮助将不胜感激。

MockMaker 是一个将 dexmaker 与 Mockito 集成的胶水模块。它执行 Mockito 使用 Dalvik .dex 文件而不是 JVM .class 文件生成具体 classes 所需的操作。

Powermock 有可能与 Dexmaker 一起使用,但高级 Powermock 功能不太可能起作用。特别是 Powermock advertises this:

PowerMock uses a custom classloader and bytecode manipulation to enable mocking of static methods, constructors, final classes and methods, private methods, removal of static initializers and more.

自定义 class 加载器不太可能在 dalvikvm 上工作。

我遇到了同样的问题,我刚刚找到了解决方案 here。它涉及一些手动工作,您将不得不自己修改 jar 文件。

那么nparihar建议如下。

  1. 备份 powermock-api-mockito-1.5.5.jar
  2. 将 powermock-api-mockito-1.5.5.jar 重命名为 powermock-api-mockito-1.5.5.zip
  3. 解压 powermock-api-mockito-1.5.5.zip
  4. cd powermock-api-mockito-1.5.5/
  5. rm -rf mockito-extensions
  6. jar cf powermock-api-mockito-1.5.5.jar META-INF/ org/
  7. 将新 jar 放入您的 libs foler。

这个解决方案对我有用。让我知道它是否也适合你。

此外,我可以看到我们使用的是相同的依赖项。就我而言,我不得不手动删除 hamcrest.jar 和 objenesis.jar,因为存在冲突。

希望对您有所帮助。

你可以试着把它放在你的 build.gradle 中,它解决了我同样的问题

android{
...

packagingOptions{
    exclude 'mockito-extensions/org.mockito.plugins.MockMaker'
}

...

}