问题
I'm trying to use PowerMock in my unit test (JUnit 4.12).
I already have Mockito integrated without any issue. This is an Android application.
When I run my unit test, no problem and the mocking of the static function works perfectly.
When I click on the "play" button in eclipse to run my app on the physical machine connected, I receive this error:
[2015-01-15 15:22:22 - Dex Loader] Unable to execute dex: Multiple dex files define Lorg/hamcrest/Description;
[2015-01-15 15:22:22 - CLAP] Conversion to Dalvik format failed: Unable to execute dex: Multiple dex files define Lorg/hamcrest/Description;
I have read that this means that PowerMock doesn't support the Delvik VM but I don't understand what this means and I can't believe that the PowerMock team or Mockito Team did not find a way to work in the Android environment!
Here is my dependencies in Maven related to PowerMock and Mockito
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>
Can anybody help me?
EDIT
I'm pretty sure all I need to do is to remove the PowerMock from my dependencies when I run my application for real (not in test) but I don't know how to do this. I'm using Eclipse so I need a solution that will work in this environment. I have checked the Profile and Exclusion from Maven but I can't see how to achieve this. I'm very new to maven. Any help will be greatly appreciated.
Also, when I remove the PowerMock dependencies (and all the unit test using it), the project now is able to run on my device without problem.
EDIT 2
With the help of the command mvn dependency:list
suggested in the comment, I have discovered this:
- JUnit have a dependency on org.hamcrest:hamcrest-core:jar:1.3:test
- PowerMock have also a dependency on the hamcrest library
It seems the problem is only happening when it's the hamcrest version of the library that is used in the project. I have tried to remove JUnit dependency and only use the powermock one and the error at launch is the same. So I don't think it's a "collision" problem but maybe a problem with the hamcrest version coming with powermock??? And I wonder why it's using at launch since it's in the "test" scope...
EDIT 3 I have created a Android project from scratch with Maven to see if it's a problem with my main application or with Maven. The problem seems to be in Maven OR in the PowerMock dependency. If you want to try, here is the complete java project. There is no unit test in this project, I only want to run it on my Android machine. I still receive the exact same message.
回答1:
I have finally fixed the problem but I don't understand everything. Thanks a lot to Eugen Martynov for his help and to this post which point me in the right direction.
The problem seems to be that Maven have a big problem with duplicated .jar files that are in nested dependencies. By using the class search, I discovered that the hamcrest class name "Description" was in my project 3 times!
So I did some research on how to exclude dependencies in Maven and discover that you can do all of this in the Maven Pom Editor. You can click on a dependencies in the dependencies tab and do "Remove".
The rest of the problem was just to remove the duplicated Hamcrest dependencies to have only one in my project. After fixing this problem, a second library had the same problem "obgenesis". I did the same fix and it finally worked.
Eugen Martynov pointed out to me in the comment that I was not using Maven at all. Maybe that's true, bear with me! At least now, I know Maven a little bit more and it does what it needed to do in my project.
Here is the final dependencies code:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.8</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>objenesis</artifactId>
<groupId>org.objenesis</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.1</version>
<scope>test</scope>
<optional>true</optional>
<exclusions>
<exclusion>
<artifactId>junit</artifactId>
<groupId>junit</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.1</version>
<scope>test</scope>
<optional>true</optional>
<exclusions>
<exclusion>
<artifactId>mockito-all</artifactId>
<groupId>org.mockito</groupId>
</exclusion>
</exclusions>
</dependency>
来源:https://stackoverflow.com/questions/27972549/powermock-mockito-maven-on-android-app-showing-dex-loader-error