Java annotation processing for Android unit testing (w/ Dagger) - android

I am attempting to set up Android unit tests in Android Studio 1.0 using DI from Dagger version 1.2.2.
Whenever I run my tests and I attempt to instantiate an ObjectGraph with my test module, I get the following error/stacktrace:
java.lang.IllegalStateException: Module adapter for class java.util.Arrays$ArrayList could not be loaded. Please ensure that code generation was run for this module.
at dagger.internal.FailoverLoader$1.create(FailoverLoader.java:45)
at dagger.internal.FailoverLoader$1.create(FailoverLoader.java:40)
at dagger.internal.Memoizer.get(Memoizer.java:56)
at dagger.internal.FailoverLoader.getModuleAdapter(FailoverLoader.java:57)
at dagger.internal.Modules.loadModules(Modules.java:43)
at dagger.ObjectGraph$DaggerObjectGraph.makeGraph(ObjectGraph.java:174)
at dagger.ObjectGraph$DaggerObjectGraph.access$000(ObjectGraph.java:138)
at dagger.ObjectGraph.create(ObjectGraph.java:129)
at com.company.app.HttpRequestManagerTest.setUp(HttpRequestManagerTest.java:35)
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)
Here is the breaking code (# ObjectGraph.create):
#Override
public void setUp() throws Exception {
super.setUp();
setContext(new MockContext());
mObjectGraph = ObjectGraph.create(Arrays.asList(new TestModule()));
mObjectGraph.inject(this);
}
Diving deeper, here is the TestModule:
package com.company.app.provider;
import dagger.Module;
#Module(
overrides = true,
library = true
)
public class TestModule {
}
It seems as though it's indicating that Java annotation processing is not active, but I don't think that's the case as I'm using other annotations such as #Override in my code without issues. I'm wondering if somehow the Dagger annotation processor is not being applied to the test build. Here is my build.gradle for what it's worth:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.1"
defaultConfig {
applicationId "com.company.app"
minSdkVersion 14
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
pickFirst 'META-INF/services/javax.annotation.processing.Processor'
}
}
ext {
daggerVersion = '1.2.2'
mockitoVersion = '2.0.3-beta'
powerMockVersion = '1.5.4'
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
compile 'com.android.support:support-v13:21.0.0'
compile 'io.realm:realm-android:0.77.0'
compile 'com.squareup.okhttp:okhttp:2.2.0'
compile 'com.jakewharton:butterknife:6.0.0'
compile "com.squareup.dagger:dagger:$daggerVersion"
provided "com.squareup.dagger:dagger-compiler:$daggerVersion"
androidTestCompile "org.mockito:mockito-core:$mockitoVersion"
}
The only fishy thing I could find here was the pickFirst 'META-INF/services/javax.annotation.processing.Processor', but that is necessary to overcome a known Butterknife issue.
Any input is greatly appreciated, thanks!

ObjectGraph.create(Arrays.asList(new TestModule()));
ObjectGraph.create is a varargs method. It does not take a List. You can either list out your modules as individual arguments or pass an Object[].
ObjectGraph.create(new TestModule());

Related

Supplied String module notation 'libs/dagger-1.2.2.jar' is invalid

I'm trying to get Mobile GTS' prebuilt Candy Jump app to run and build an APK in Android Studio. I've followed this video precisely: https://www.youtube.com/watch?v=YpYVdJVYWg0.
However, I am using Gradle 4.7, JDK 1.8.0, Android Plugin Version 3.1.2 and Build Tools Version 27.0.3. I'm not sure if that would have anything to do with why I can't get it to build, but I've had error after error and I've kind of boiled it down to what I hope is the last error.
Supplied String module notation 'libs/dagger-1.2.2.jar' is invalid. Example notations: 'org.gradle:gradle-core:2.2', 'org.mockito:mockito-core:1.9.5:javadoc'.
How can I fix this error?
Here's my build.gradle (module: app)
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
buildToolsVersion '27.0.3'
defaultConfig {
applicationId "net.mobilegts.candyjump"
minSdkVersion 19
targetSdkVersion 27
multiDexEnabled true
ndk {
moduleName "player_shared"
}
}
buildTypes {
release {
minifyEnabled false
shrinkResources false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
sourceSets.main {
jni.srcDirs = []// <-- disable automatic ndk-build call
}
productFlavors {
}
}
dependencies {
implementation('com.google.android.gms:play-services:+') { exclude module: 'support-v4' }
implementation 'libs/dagger-1.2.2.jar'
implementation 'libs/javax.inject-1.jar'
implementation 'libs/nineoldandroids-2.4.0.jar'
implementation 'libs/support-v4-19.0.1.jar'
implementation 'com.android.support:multidex:1.0.3'
implementation 'com.android.support:support-core-utils:27.1.1'
}
You should use "implementation files" for jar files. Try the following code:
implementation files('libs/dagger-1.2.2.jar')
implementation files('libs/javax.inject-1.jar')
implementation files('libs/nineoldandroids-2.4.0.jar')
implementation files('libs/support-v4-19.0.1.jar')

error while building the apk in android

This is the my build.gradle and when I build the apk by clicking on the build apk this error shown.I have seen the some of the queries before but not able to figure out the problem solution
Error:Execution failed for task ':app:transformClassesWithDexForDebug'.
com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
applicationId "com.example.ranjeet.location"
minSdkVersion 14
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
compile 'com.android.volley:volley:1.0.0'
compile 'com.google.code.gson:gson:2.8.0'
compile 'com.google.android.gms:play-services:10.2.6'
compile 'com.google.android.gms:play-services-maps:10.2.6'
}
You have too many methods. There can only be 65536 methods for dex.
So, enable multidex as following:
android {
defaultConfig {
// Enabling multidex support.
multiDexEnabled true
}
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
You have too many methods. There can only be 65536 methods for dex.
So, enable multidex as following:
android {
defaultConfig {
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
And paste this code as well,
dexOptions {
javaMaxHeapSize "4g"
preDexLibraries = false
}
com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536
The underlying problem is imposed by the current set of Dalvik instructions. Specifically, any of the invoke-* methods. These expect a 16-bit argument, representing the target method's reference index. Being limited to 16-bits, valid values are between 0 and 65536. This means, that if you end up calling more than 65,536 defined methods, you are going to exceed this limit.
Solutions:
MultiDex allows you to use multiple DEX files contained within one APK. With a few steps, your classes will split automatically into several DEX files (classes.dex, classes2.dex, classes3.dex, etc) in case you reach the method index limit.
Get more infomation : https://www.contentful.com/blog/2014/10/30/android-and-the-dex-64k-methods-limit/
If your minSdkVersion is set to 21 or higher, all you need to do is set multiDexEnabled to true in your app-level build.gradle file, as shown here:
android {
defaultConfig {
...
minSdkVersion 21
targetSdkVersion 25
multiDexEnabled true
}
...
}
However, if your minSdkVersion is set to 20 or lower, then you must use the multidex support library as follows:
Modify the app-level build.gradle file to enable multidex and add the multidex library as a dependency, as shown here:
android {
defaultConfig {
...
minSdkVersion 15
targetSdkVersion 25
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.1'
}
Create an Application class like this:
public class MyApplication extends MultiDexApplication {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
Add this application class in Manifest.
You can also check this link:
https://developer.android.com/studio/build/multidex.html

Android prob with AndroidJUnitRunner giving 'java.lang.ClassNotFoundException'

I am new in Instrumentation testing. I am trying basic testing with AndroidJUnitRunner. Here is my gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "25.0.0"
defaultConfig {
applicationId "com.kaushik.mycart.ui"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
jackOptions.enabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
..........................
..........................
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
}
Then I added a class named 'ProductListActivityTest' to test with AndroidJunitRunner. It is below:
package com.kaushik.myredmart.ui;
// all includes
#RunWith(AndroidJUnit4.class)
public class ProductListActivityTest {
#Rule
public ActivityTestRule<ProductListActivity> rule = new ActivityTestRule<>(ProductListActivity.class);
#Test
public void ensureListViewIsPresent() throws Exception {
ProductListActivity activity = rule.getActivity();
View viewByIdw = activity.findViewById(R.id.productListView);
assertThat(viewByIdw,notNullValue());
assertThat(viewByIdw, instanceOf(RecyclerView.class));
RecyclerView productListView = (RecyclerView) viewByIdw;
RecyclerView.Adapter adapter = productRecyclerView.getAdapter();
assertThat(adapter, instanceOf(ProductAdapter.class));
}
}
I have added no other file in 'androidTest'. I like to also mention that there is Application class file in my source code. Now every time I try to run the test, it is giving following error:
Started running tests
Test running failed: Instrumentation run failed due to 'java.lang.ClassNotFoundException'
Empty test suite.
Can anyone help me identifying the problem in my test code?
How are you running your tests?
If you are doing it from Android Studio:
Open Run menu -> Edit Configurations
Add a new Android Tests configuration
Choose a module
Add a specific instrumentation runner:
android.support.test.runner.AndroidJUnitRunner
From command-line via Gradle:
./gradlew connectedAndroidTest
I solved the problem. It is due to difference of Package names. I set all package name uniform and run again. It works. Thank you all for helping.

Android Studio Junit tests package org.junit does not exist

I'm trying to implement a test class in Android Studio to make some test on a DBAdapter. Since I need to run the test on my mobile phone in order to use the database, I have created an Instrumentation Unit Test (cause I've tried to do it just with a Unit test but I need to use the database and so, and those are only run locally).
The problem is that when I try to run the test class, using my mobile phone as running device, the compiler throws the following error:
error: package org.junit does not exist
I've been looking for a solutione, but I found none.
This is my test class (just the skeleton):
import org.junit.Test;
import android.support.test.runner.AndroidJUnit4;
import static org.junit.Assert.*;
public class DbAdapterTest {
#Test
public void testCreateSeries() throws Exception {
}
}
And this one is the build.gradle script:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.w2w.whattowatch"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
testOptions {
unitTests.returnDefaultValues = true
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
testCompile 'junit:junit:4.12'
testCompile "org.mockito:mockito-core:1.9.5"
}
I also have another issue. As you can see, I also imported this:
import android.support.test.runner.AndroidJUnit4;
But, even before running, it says of "runner" that "cannot resolve the symbol". I've added the TestInstrumentationRunner on build.gradle, but still not working.
OK, I solve it so, this is the solution that worked for me.
I didn't have this dependences, so I add them to the build.gradle script:
androidTestCompile 'com.android.support:support-annotations:23.1.1'
androidTestCompile 'com.android.support.test:runner:0.4.1'
androidTestCompile 'com.android.support.test:rules:0.4.1'

NoClassDefFoundError using Jackson 2.2.x on Android with Gradle

For my Android project I set up Gradle with Jackson 2.2.x as follows:
// build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6.+'
}
}
apply plugin: 'android'
repositories {
mavenCentral()
}
android {
compileSdkVersion 18
buildToolsVersion "18.1.0"
defaultConfig {
minSdkVersion 8
targetSdkVersion 18
}
}
dependencies {
compile 'com.android.support:appcompat-v7:18.0.0'
compile 'com.android.support:support-v4:18.0.0'
compile 'com.google.android.gms:play-services:3.1.36'
compile 'com.fasterxml.jackson.core:jackson-databind:2.2.+'
compile 'com.fasterxml.jackson.core:jackson-core:2.2.+'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.2.+'
}
I simply use the ObjectMapper here:
import com.fasterxml.jackson.databind.ObjectMapper;
// ...
ObjectMapper objectMapper = new ObjectMapper();
try {
Content content = objectMapper.readValue(inputStream, Content.class);
} catch (IOException e) {
e.printStackTrace();
}
When I run gradle installDebug and launch the relevant part of the application it crashes:
java.lang.NoClassDefFoundError: com.fasterxml.jackson.databind.ObjectMapper
Thoughts:
I noticed that in the error message com.fasterxml.jackson... is mentioned while com.fasterxml.jackson.core is defined in build.gradle. Is there a mismatch causing the problem?
I temporarily moved the dependencies block into the android block since I found other build.gradle configurations structured this way. However it seems to make no difference.
Gradle and Android don't always place nicely with dependencies(yet). Running
gradle clean
seems to fix most problems for me.
Note: If that didn't work, you can run
dexdump classes.dex | grep 'Class descriptor'
on the classes.dex file in the APK. That will check to see if the class is included in the classes.dex file. (Sometimes it's useful if you want to double check whats going on).
Gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "com.app.test"
minSdkVersion 9
targetSdkVersion 22
versionCode 4
versionName "1.3"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:22.2.0' `enter code here`
compile 'com.fasterxml.jackson.core:jackson-databind :2.5.3'
}
Add permission and dependency into you Gradle and then build gradle you will get Object wrapper class

Categories

Resources