19

Like many others I was excited to hear that Mockito now works with Android and followed this tutorial to see it with my own eyes. Everything seemed fan-flapping-tastic and I got underway incorporating the mocking solution into my Android Test Project...

The error

However, on setting up my application's test project to leverage the mockito-all-1.9.5, dexmaker-1.0 and dexmaker-mockito-1.0 jars I encountered a problem with my very first test case. Precisely this problem in fact. The part that I would like assistance on is;

Caused by: java.lang.VerifyError: org/mockito/cglib/core/ReflectUtils
at org.mockito.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:167)
at org.mockito.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:217)
at org.mockito.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:117)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:109)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:105)
at org.mockito.cglib.proxy.Enhancer.<clinit>(Enhancer.java:70)

I have been informed that this "simply doesn't quite work yet" since the stack trace implies that the DexMaker jar is not being used - reference this response. However, I am suspicious that I am doing something wrong with respect to my project set-up so I'm looking to draw from the collective knowledge base here to see if indeed this is user error or a beta-bug.

My Android Test Project set-up

Please find below a screenshot of my test project's configuration. The project was created via the Android Wizard and shares no special features other than the inclusion of the Mockito and DexMaker jars (mentioned above) under the libs directory.

Test Project Configuration

The Test

Never mind the content of the test (the test fails before the unit test is executed) the set-up is as described below;

public class TestSpotRatingCalculator extends InstrumentationTestCase {
  @Mock
  private AService aService; // Changed the service names being used here - not important.
  @Mock
  private BService bService;
  @Mock
  private CService cService;
  @Mock
  private DService dService;

  /**
   * @see android.test.AndroidTestCase#setUp()
   */
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    MockitoAnnotations.initMocks(this);  // Failure here with aforementioned stacktrace...
  }

If anyone out there has an idea what is wrong then please sound-off here.

BrantApps
  • 6,362
  • 2
  • 27
  • 60
  • 1
    Agreed, dexmaker doesn't seem to be used, or seen at all in the runtime. I'm not an Android dev but this is definitely the case here. – bric3 Oct 24 '12 at 13:05
  • Thanks @Brice - any help on this is great and gives me something to go back to the developers with. I'll point them at this question and your comment and see how we get on... – BrantApps Oct 25 '12 at 07:26
  • Just a note to help searchers... The error described here also occurs if you're trying to use Mockito on Android *without* dexmaker. In that case, add the two dexmaker jars to your `libs/` directory and build classpath. – Brian White Jan 01 '14 at 02:32
  • Did you solve this? I have the same problem http://stackoverflow.com/questions/24967050/cant-run-android-test-with-mockito-powermockito – Llamalo_X Jul 26 '14 at 16:11

5 Answers5

12

Hi I had the same problem and I found this article really usefull!

http://corner.squareup.com/2012/10/mockito-android.html

The key piece of information is:

To use Mockito on a device or emulator, you’ll need to add three .jar files to your test project’s libs directory: mockito-all-1.9.5.jar, dexmaker-1.0.jar, and dexmaker-mockito-1.0.jar.

David
  • 2,429
  • 24
  • 15
Shilaghae
  • 957
  • 12
  • 22
9

Just add this in your gradle:

androidTestCompile 'org.mockito:mockito-core:1.10.8'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.1'
user1007522
  • 7,858
  • 17
  • 69
  • 113
  • Anyone else getting `java.lang.IllegalArgumentException: dexcache == null` when attempting this? – Nilzor Dec 14 '15 at 11:02
5

We just had the same problem in a project, but our tests also failed on a real device.

The cause was tracked to how Mockito uses the class loader, and resulted in the following error in LogCat:

W/ActivityThread(5777): ClassLoader.getResources: The class loader returned by Thread.getContextClassLoader() may fail for processes that host multiple applications. You should explicitly specify a context class loader. For example: Thread.setContextClassLoader(getClass().getClassLoader());

The fix was to explicitly set the class loader before calling mock() a test, eg.

@Override
protected void setUp() throws Exception {
    super.setUp();
    Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
    fooImpl = mock(Foo.class)
}

The problematic file in Mockito is this one: org.mockito.internal.configuration.ClassPathLoader (line 121 in 1.9.5)

Christian Melchior
  • 19,978
  • 5
  • 62
  • 53
  • 1
    Thanks for pointing that out! I was experiencing a java.lang.VerifyError when attempting to mock a class, even after including the dexmaker jars. This was done using Mockito 1.9.5. Adding that to the setUp method got rid of the error. – Ivan Aug 08 '13 at 01:06
2

As hinted at here the dexmaker-android combo only works 100% when the instrumented tests are run against a real device.

Running the tests against a real device do not exhibit this failure.

BrantApps
  • 6,362
  • 2
  • 27
  • 60
1

For everybody who still have this error, check if you didn't exclude a class in the dependecies. We exluded by accident the MockMaker.class so this was then the cause for the exception.

mapodev
  • 988
  • 8
  • 14