I am trying to implement robolectric testing in an existing app. I can run simple static tests but when I add testing with ActiveAndroid I get NullPointerExceptions, I think ActiveAndroid can not be found when the unit test is being run.
Im not sure maybe there are some configurations for ActiveAndroid for Robelectric unit testing. Kindly help me on this one.
This is the project structure:
MainApp
-src/main
-src/test
LibraryApp
-src/main/models <--- here are my models and classes for active android
-libs/activeandroid-3.0.jar <---- the active android jar file
I imported ActiveAndroid-3.0.jar in the Library App.
Here are the build.gradle files:
MainApp build.gradle
android {
compileSdkVersion 21
buildToolsVersion "22.0.0"
defaultConfig {
applicationId "com....."
minSdkVersion 18
targetSdkVersion 21
versionCode 1
versionName "1.0"
// Enabling multidex support.
multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dexOptions {
preDexLibraries = false
}
sourceSets {
main {
java {
exclude 'com/google/gson/annotations/Expose.class'
}
}
}
lintOptions{
abortOnError false
}
packagingOptions{
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE.txt'
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile files('libs/gcm.jar')
compile 'com.android.support:multidex:1.0.1'
compile 'joda-time:joda-time:2.9.1'
androidTestCompile 'junit:junit:4.12'
testCompile 'junit:junit:4.12'
compile 'com.facebook.fresco:fresco:0.7.0+'
compile 'com.github.bluejamesbond:textjustify-android:2.1.0'
compile files('libs/activeandroid-3.0.jar')
compile 'com.google.android.gms:play-services:7.5.0'
compile 'com.jakewharton:butterknife:7.0.1'
compile files('libs/FlurryAnalytics-5.5.0.jar')
compile project(':app')
androidTestCompile 'com.android.support.test:runner:0.3'
testCompile 'com.android.support.test:runner:0.3'
androidTestCompile 'com.android.support.test:rules:0.3'
testCompile 'com.android.support.test:rules:0.3'
// Set this dependency to build and run Espresso tests
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2'
// Set this dependency to build and run UI Automator tests
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1'
//compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
//classpath 'com.stanfy.spoon:spoon-gradle-plugin:1.0.2'
compile 'com.github.jakob-grabner:Circle-Progress-View:v1.2.2'
compile('com.crashlytics.sdk.android:crashlytics:2.5.5@aar') {
transitive = true;
}
testCompile "org.robolectric:robolectric:3.0-rc3"
testCompile 'junit:junit:4.12'
testCompile "org.robolectric:shadows-multidex:3.0"
}
LibraryApp build.gradle
apply plugin: 'com.android.library'
android {
compileSdkVersion 21
buildToolsVersion "22.0.0"
defaultConfig {
minSdkVersion 18
targetSdkVersion 22
versionCode 1
versionName "1.0"
// Enabling multidex support.
multiDexEnabled false
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dexOptions {
preDexLibraries = false
}
packagingOptions{
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
}
configure(android.lintOptions) {
abortOnError false
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.balysv.materialmenu:material-menu-toolbar:1.5.4'
compile 'org.lucasr.twowayview:twowayview:0.1.4'
compile files('libs/gson-2.3.1.jar')
compile 'org.apache.httpcomponents:httpmime:4.2.3'
compile files('libs/activeandroid-3.0.jar')
compile 'com.google.code.gson:gson:2.3.1'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'com.scottyab:aescrypt:0.0.1'
compile 'com.android.support:multidex:1.0.1'
testCompile "org.robolectric:robolectric:3.0-rc3"
testCompile 'junit:junit:4.12'
testCompile "org.robolectric:shadows-multidex:3.0"
}
Here is my unit test,
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP, shadows= {ShadowMultiDex.class})
public class MyActivityTest {
Activity activity = null;
@Before
public void init(){
}
@Test
public void getMillisecondFromHourTest(){
}
}
If I run the unit test with a custom Application class where ActiveAndroid.initialize(this); where is not being called my unit tests run (only those static asserts).
If I use an Application class the calls ActiveAndroid.initialize(this); this happens:
java.lang.NullPointerException
at dalvik.system.DexFile$DFEnum.hasMoreElements(DexFile.java:262)
at com.activeandroid.ReflectionUtils.getParsers(ReflectionUtils.java:152)
at com.activeandroid.Registry.initialize(Registry.java:100)
at com.activeandroid.ActiveAndroid.initialize(ActiveAndroid.java:8)
at com.activeandroid.app.Application.onCreate(Application.java:9)
at com.MyApplication.onCreate(MyApplication.java:28 1)
at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:140)
at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:433)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:240)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
java.lang.RuntimeException: java.lang.NullPointerException
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:244)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.NullPointerException
at dalvik.system.DexFile$DFEnum.hasMoreElements(DexFile.java:262)
at com.activeandroid.ReflectionUtils.getParsers(ReflectionUtils.java:152)
at com.activeandroid.Registry.initialize(Registry.java:100)
at com.activeandroid.ActiveAndroid.initialize(ActiveAndroid.java:8)
at com.activeandroid.app.Application.onCreate(Application.java:9)
at com.MyApplication.onCreate(MyApplication.java:281)
at org.robolectric.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:140)
at org.robolectric.RobolectricTestRunner.setUpApplicationState(RobolectricTestRunner.java:433)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:240)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
... 1 more
By the way. I have this in my MyApplication.class also
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
ShadowMultiDex.class
is the one responsible for doing that. Is that correct? I also tried your suggestion before and again today, but still it always fails on ActiveAndroid.initialize(this). – Gunthar