I’m writing this post as a PSA for anyone else who is pulling their hair out over this. I started getting the following exception when trying to run tests in Robolectric with Mockito.
java.lang.IllegalArgumentException: dexcache == null (and no default could be found; consider setting the 'dexmaker.dexcache' system property)
at com.google.dexmaker.DexMaker.generateAndLoad(DexMaker.java:359)
at com.google.dexmaker.stock.ProxyBuilder.buildProxyClass(ProxyBuilder.java:252)
at com.google.dexmaker.mockito.DexmakerMockMaker.createMock(DexmakerMockMaker.java:56)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:26)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:51)
at org.mockito.Mockito.mock(Mockito.java:1243)
at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:30)
at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:16)
at org.mockito.internal.configuration.DefaultAnnotationEngine.createMockFor(DefaultAnnotationEngine.java:43)
at org.mockito.internal.configuration.DefaultAnnotationEngine.process(DefaultAnnotationEngine.java:66)
at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:71)
at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:55)
at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:108)
at xxx.anpr.handheld.model.when_creating_a_XXX_label.setUp(when_creating_a_XXX_label.java:50)
at sun.reflect.GeneratedMethodAccessor38.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:236)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:177)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Hunting the internet revealed no one, as far as I could see, who’d suffered the same problem. Worse than that, I’d set up the same sort of thing in a different project without hitting this problem.
But, flash of inspiration. The problem is with dexcache. Well dex is kind of like the android version of Java byte code (in a very handwavey kind of way). But this is in Robolectric. We shouldn’t be dealing in dex, we should be dealing in good old fashioned byte code, like our fathers and their fathers before them. And then it hit me, an ingenious work around.
Mockito only started supporting android relatively recently. If I drop back to version 1.9 it won’t even know to try this dexcache thing! So remove the reference to version 1.9.5, replace it with 1.9.0 and Bob’s your uncle, working Mocks!
Fixed then, but not fixed that well.
workaround for this issue: (add this line on setUp())
System.setProperty(“dexmaker.dexcache”, getInstrumentation().getTargetContext().getCacheDir().getPath());
more details here:
http://code.google.com/p/dexmaker/issues/detail?id=2
Hey thats not works getInstrumentation is for JUnit 3 and Robolectric use JUnit 4
Hello, that fix not work
Robolectric use JUnit4 not JUnit3 and you will not use InstrumentationTestCase thats why you can call getInstrumentation()
If anybody knows the solution to this issue please help me
Thanks for this. After pulling my hair for over a day, this made me realize I needed normal mockito (‘org.mockito:mockito-core:1.+’ in gradle) and not the dexmaker version which you normally use on Android (‘com.google.dexmaker:dexmaker-mockito:1.0’)
Thank you Phil, you just made my day! I have been struggling with this problem two entire days!
I have lost enough hair as it is. This post should be the FIRST LINK that comes up on Google. This worked. THANK YOU THANK YOU THANK YOU!