Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Mockito/Hamcrest in unit tests in Android Studio

I want to be able to make unit tests and instrumentation tests in Android Studio, and using Mockito in them.

I'm using the new approach for tests in Android Studio 0.8. This is:

  • building with gradle
  • using official Android API for testing (ActivityInstrumentationTestCase2, etc)
  • having the tests inside the directory of the app, not as a separate module
  • launching the tests in Android Studio as a "Android Test" run configuration

How can I write code in my tests that depends on libraries used only for the tests, such as mockito or hamcrest?

I'd like to include these libraries when compiling and running the tests, but avoid them to be exported to the released .apk.

In https://code.google.com/p/mockito/wiki/DeclaringMockitoDependency I've read that I should add the dependency as:

dependencies {
    ....
    testCompile "org.mockito:mockito-core:1.9.5"
}

But when running I get:

Build script error, Unsupported Gradle DSL method found: 'testCompile()'!

Although I'm not sure it's relevant, the gradle build file I'm using is:

apply plugin: 'android'

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    compile project(':android-sdk')
    testCompile "org.mockito:mockito-core:1.9.5"
}

android {
    compileSdkVersion 19
    buildToolsVersion "20.0.0"

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        // Move the tests to tests/java, tests/res, etc...
        androidTest.setRoot('tests')

        // Note - to run the tests from command line:
        // $ gradle clean connectedCheck build
        // (requires gradle 1.10)

        // Move the build types to build-types/<type>
        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
        // This moves them out of them default location under src/<type>/... which would
        // conflict with src/ being used by the main source set.
        // Adding new build types or product flavors should be accompanied
        // by a similar customization.
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
}
like image 700
GaRRaPeTa Avatar asked Aug 18 '14 16:08

GaRRaPeTa


People also ask

What is Mockito in JUnit Android?

Mockito is a mocking framework that tastes really good. It lets you write beautiful tests with a clean & simple API. Mockito doesn't give you hangover because the tests are very readable and they produce clean verification errors.

Can we use Mockito without JUnit?

Mockito is a mocking framework. It is a Java-based library used to create simple and basic test APIs for performing unit testing of Java applications. It can also be used with other frameworks such as JUnit and TestNG.


2 Answers

I got it working by using the "androidTestCompile" options under "dependencies", as explained here.

What I have done is:

  • created a folder called libs-tests with the jars that should only be used for testing.
  • added that folder as a dependency for tests with "androidTestCompile"

Now, the gradle build file stands as:

apply plugin: 'android'

dependencies {
    compile project(':android-sdk')

    // The libs folder is included in the apk of the real app
    compile fileTree(dir: 'libs', include: '*.jar')

    // The tests-libs folder is included only for tests
    androidTestCompile fileTree(dir: 'libs-tests', include: '*.jar')
}


android {
    compileSdkVersion 19
    buildToolsVersion "20.0.0"

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }


    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        // Move the tests to tests/java, tests/res, etc...
        androidTest.setRoot('tests')

        // Note - to run the tests from command line:
        // $ gradle clean connectedCheck build
        // (requires gradle 1.10)

        // Move the build types to build-types/<type>
        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
        // This moves them out of them default location under src/<type>/... which would
        // conflict with src/ being used by the main source set.
        // Adding new build types or product flavors should be accompanied
        // by a similar customization.
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
}
like image 161
GaRRaPeTa Avatar answered Nov 09 '22 05:11

GaRRaPeTa


I had that exact problem too.

  1. I used androidTestCompile instead of testCompile
  2. I also had to have the classpath 'com.android.tools.build:gradle:1.1.0' [or higher]
  3. then i did a buildDependecies before doing a sync.

thats all i did for this error to go away.

like image 36
nyxee Avatar answered Nov 09 '22 06:11

nyxee