14

So I've been struggling pretty much all day trying to get Mockito to work for my Android project. I added everything to my Gradle build file:

androidTestCompile 'org.mockito:mockito-core:2.0.29-beta'
androidTestCompile "junit:junit:4.12-beta-3"
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'

and have tried running a test that doesn't really do anything:

@RunWith(MockitoJUnitRunner.class)
public class LoginActivityTest extends 
    ActivityInstrumentationTestCase2<LoginActivity> {

    private LoginActivity loginActivity;

    private EditText et_email;
    private EditText et_password;
    private Button btn_login;

    @Mock
    SpiceManager manager;

    public LoginActivityTest(){
        super(LoginActivity.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();
        loginActivity = getActivity();

        MockitoAnnotations.initMocks(this);
        //manager = mock(SpiceManager.class);
        loginActivity.spiceManager = manager;

        et_email = (EditText) loginActivity.findViewById(R.id.et_email);
        et_password = (EditText) loginActivity.findViewById(R.id.et_password);
        btn_login = (Button) loginActivity.findViewById(R.id.btn_login);
    }

    @Override
    public void tearDown() throws Exception {
        super.tearDown();
    }

    public void testLoginEmpty() throws Exception {        
        verify(manager).execute(
            any(LoginRequest.class), 
            anyString(), 
            anyLong(), 
            any(LoginActivity.LoginRequestListener.class));
    }
}

The reason I want to mock the service is because I would like to keep the network part out the test. There's no need to actually send a network request for a simple test, right?

Anyhow, the app builds but when the actual test starts running it fails (or rather crashes) with an AbstractMethodError:

Running tests
Test running started
java.lang.AbstractMethodError: abstract method     
    "org.mockito.plugins.MockMaker$TypeMockability 
    org.mockito.plugins.MockMaker.isTypeMockable(java.lang.Class)"

at org.mockito.internal.util.MockUtil.typeMockabilityOf(MockUtil.java:26)
at org.mockito.internal.util.MockCreationValidator.validateType(MockCreationValidator.java:21)
at org.mockito.internal.creation.MockSettingsImpl.validatedSettings(MockSettingsImpl.java:167)
at org.mockito.internal.creation.MockSettingsImpl.confirm(MockSettingsImpl.java:161)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:58)
at org.mockito.Mockito.mock(Mockito.java:1410)
at org.mockito.Mockito.mock(Mockito.java:1288)
at be.sanmax.membr.activities.LoginActivityTest.setUp(LoginActivityTest.java:50)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1837)

This strikes me as odd since the SpiceManager class does not contain any abstract methods. It is, however, part of some package that I didn't write (com.octo.android.robospice). But that shouldn't be an issue. Should it?

And if that is the issue, how could I go about factoring it out from any tests? I only want to test the working of the app, not the network connection...

JJD
  • 50,076
  • 60
  • 203
  • 339
killernerd
  • 377
  • 2
  • 6
  • 21
  • Run unit tests in `tests` not `androidTest`. Try not to use annotations. Do this: `SpiceManager manager = Mockito.mock(SpiceManager.class);` – Jared Burrows Jul 14 '15 at 14:28
  • didn't know there was a difference? android studio only allows me to make either a normal package or an "androidTest" package. And if you look in the code snippet you'll see that exact line commented out because it didn't work either. – killernerd Jul 14 '15 at 14:49
  • @SkinnyJ that has nothing to do this with question – Jared Burrows Jul 14 '15 at 16:21
  • @SkinnyJ not really the same error nor does that question have a solution. BTW, I forgot to put it in the question but the error occurs at the "MockitoAnnotations.initMocks(this)" line. I could go for "manual" mocking but mockito will make my life a whole lot easier. – killernerd Jul 15 '15 at 07:23
  • Still haven't been able to solve this issue. I guess manual mocking is my only option here? Or perhaps some other mocking library? – killernerd Jul 17 '15 at 12:36
  • 1
    I'm having the same issue when using the Mockito.mock() call. Going back to mockito-core:2.0.17-beta works though, they changed something in version 2.0.18 that breaks (for me at least) mocking in Android. – Denis Lapuente Aug 18 '15 at 11:27

5 Answers5

16

Dexmaker does not support Mockito 2.0 since the definition of MockMaker has changed. I suggest you use Mockito 1.10.19 but then you will run into this NPE for which I have submitted a fix.

Looks like my fix is now merged into dexmaker as of version 1.5

Andy Piper
  • 563
  • 4
  • 10
  • 1
    Can you please reference where you read that Mockito 2.0 is not supported by Dexmaker? Also, I am interested if the support is on the roadmap for later. – JJD Sep 17 '15 at 20:38
  • 1
    I did not read that it did not support it - I simply tried building dexmaker with Mockito 2.0 and it did not work for me because of API changes. I have no idea what the release schedule is, but my pull request is still languishing so I don't get the impression that dexmaker is as actively maintained as it could be. – Andy Piper Sep 28 '15 at 10:34
  • 2
    Indeed, I was using `2.0.42-beta` when getting this error. Switching back to `1.10.19` solved the issue for me. – IgorGanapolsky Feb 24 '16 at 19:35
  • I tried with mockito up to 2.0.17-beta it works well, but newer versions don't work. – ultraon Jun 24 '16 at 23:00
14

For me it helped to use newest dexmaker (and remove all other powermock/mockito dependencies):

    androidTestCompile 'com.linkedin.dexmaker:dexmaker-mockito:2.2.0'
Jonas
  • 2,096
  • 20
  • 17
  • This did work for me, but it was important to remove the other existing dependencies (like original answer mentioned). FWIW, I couldn't find a 2.2.0 version, but used a 2.19.0 versions (and I know this is constantly changing and being updated) – Booger Jun 22 '18 at 19:31
2

Use mockito-android instead of mockti-core for instrumentation tests.

Akhil Tiwari
  • 264
  • 3
  • 15
1

Mockito.initAnnotations and @RunWith are incompatible to each other. They both initialize the annotations. Try to remove one of the two. I suggested to keep the runner.

JJD
  • 50,076
  • 60
  • 203
  • 339
Gualtiero Testa
  • 244
  • 1
  • 3
  • 8
  • hmmm, I tried that but then it comes up with a "nullInsteadOfMockException" error where it states that "if you use @Mock annotations don't miss initMocks()". So where does that come in then? – killernerd Jul 27 '15 at 08:40
  • Strange. I never use initMocks() when I have MockitoRunner as Runner. See for reference [http://mockito.googlecode.com/hg-history/1.6/javadoc/org/mockito/MockitoAnnotations.html] Eventually yoy could try using Mockito without annotations (Mockito.mock) – Gualtiero Testa Jul 27 '15 at 08:55
-1

For me it helped switching from mockito to powermock. Downgrading mockito to 1.x gave me the null exception, updgrading to 2.x gave me the AbstractMethodError. Just include in dependencies (instead of mockito):

testCompile "org.powermock:powermock-module-junit4:1.6.5"
testCompile "org.powermock:powermock-module-junit4-rule:1.6.5"
testCompile "org.powermock:powermock-api-mockito:1.6.5"
testCompile "org.powermock:powermock-classloading-xstream:1.6.5"
Mihaela Romanca
  • 1,368
  • 2
  • 14
  • 23