5

I added the following dependencies to my android project:

 // Unit testing dependencies
androidTestCompile 'junit:junit:4.12'
// Set this dependency if you want to use Mockito
androidTestCompile 'org.mockito:mockito-core:1.10.19'

And create a test using junit4 api (an example, Adder is a simple class that sums ints):

@RunWith(MockitoJUnitRunner.class) 
public class AdderTest {

    @Test
    public void testValidAdd() {
        Adder adder = new Adder();
        assertEquals(adder.add(1,1), 2);
    }
}

When I try to run the test, I get:

Running tests Test running started junit.framework.AssertionFailedError: No tests found in com.test.myapp.AdderTest at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191) at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176) at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701) Finish

I read here and here, but nothing helps.

Does anyone see what I'm doing wrong / have any input?

Community
  • 1
  • 1
dors
  • 5,802
  • 8
  • 45
  • 71
  • Unit tests belong in the `test` folder, so use `testCompile`. Also, you do not need the `@RunWith(MockitoJUnitRunner.class)`. – Jared Burrows Aug 07 '15 at 18:28
  • This was just an example. I do need in my original project to use mocks. In addition, the code that I'm testing uses android.util.Patterns.EMAIL_ADDRESS, and it returns null when I run it as a unit test. If I run it as an Android instrumentation test, won't it return the actual matcher? – dors Aug 07 '15 at 19:59
  • Post your code for clarity. You should be using Robolectric for unit testing. It will instrument the classes you need so you do not need mocks *for everything*. – Jared Burrows Aug 07 '15 at 20:01
  • I do need to use Mockito to mock some responses of class dependencies. Using @RunWith(RobolectricTestRunner.class) in the test class + adding MockitoAnnotations.initMocks(this); to my setup() method does make my test work as a unit test (android.util.Patterns.EMAIL_ADDRESS does not return null). Is this the way to go though? It seems complex :/ – dors Aug 07 '15 at 20:29
  • It is not complex at all. Please see my Android Gradle Templaet here: https://github.com/jaredsburrows/AndroidGradleTemplate/blob/master/Example-AllLibraries/build.gradle – Jared Burrows Aug 07 '15 at 21:38

2 Answers2

16

These aren't unit tests, they are instrumentation test. I had the same problem and solved it by adding these lines to module's build.gradle:

android {
    ...
    sourceSets {
        ...
        defaultConfig {
            testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
        }
    }
}

You have to add the runner in dependencies, i suggest you espresso:

androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'

EDIT:

I have forgotten about the annotation. Just remove @RunWith and make a @Before method with line:

MockitoAnnotations.initMocks(this);

or:

System.setProperty("dexmaker.dexcache", InstrumentationRegistry.getTargetContext().getCacheDir().getPath());

I have to mention this way is not recommended. To use the second one, you have to add dependencies with dex-maker for mockito:

androidTestCompile ('com.google.dexmaker:dexmaker-mockito:1.2') {
        exclude module: 'mockito-core'
    }

Since you have added mockito, we have to exclude mockito core from the new dependency. It already contains the normal dex-maker module.

Szymon Gałązka
  • 249
  • 2
  • 11
  • 1
    @IgorGanapolsky The line you're looking for is in [app/build.gradle](https://github.com/googlesamples/android-topeka/blob/master/app/build.gradle#L29). This seems to support the statement that the `testInstrumentationRunner` directive is required. – Jeff Bowman Jan 22 '16 at 20:03
2

You're using an Android Instrumentation test. By default, the Android test runner doesn't run on JUnit4, it runs on JUnit3 using subclasses of InstrumentationTestCase.

You'll need to revert to manual calls to MockitoAnnotations.initMocks(), with an optional tear-down call to Mockito.validateMockitoUsage(). Of course, calls directly to Mockito.mock (and such) will still work.

As an alternative, there is an official JUnit4 runner, which can be installed from the Android Support Test Library. By invoking this Instrumentation rather than the default test runner, you can run JUnit4 tests on your device, including using MockitoJUnitRunner or MockitoRule.

Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
  • Actually, the default runner for modern Android gradle projects is Junit 4 now. – IgorGanapolsky Jan 21 '16 at 17:26
  • 1
    @IgorGanapolsky Sure, but only if you set the instrumentation test runner as Szymon's answer. The built-in runner is JUnit3.8, so an override is still required; once it is overridden you're using the Android Support Test Library as in my answer. – Jeff Bowman Jan 21 '16 at 17:35