How to set up Mockito for Kotlin and Android - android

I want to use Mockito for unit testing, so I added the Mockito library into my gradle dependencies.
testImplementation 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:2.12.0'
But still, I can not use any Mockito annotations.
/androidTest/ExampleTest.kt
#RunWith(MockitoJUnitRunner::class) // Unresolved reference MockitoJUnitRunner
#Mock // Unresolved reference Mock
What I'm missing it?

You need to add the following dependencies in your app's build.gradle:
dependencies {
// ... more entries
testCompile 'junit:junit:4.12'
// required if you want to use Mockito for unit tests
testImplementation 'org.mockito:mockito-core:2.24.5'
// required if you want to use Mockito for Android tests
androidTestImplementation 'org.mockito:mockito-android:2.24.5'
}
And click on sync

You may need another dependency:
androidTestCompile 'org.mockito:mockito-android:2.12.0'
Alternatively, you can try manually importing the annotations:
import static org.mockito.Mockito.*;
It could be that it didn't import properly and that's why it showed as an unresolved reference. Auto-import has its flaws

I have faced an issue with assembleDebugAndroidTest which is related to objenesis. So, based on Shylendra's answer, you may want to replace
androidTestImplementation 'org.mockito:mockito-android:2.24.5'
with
androidTestImplementation("org.mockito:mockito-core:2.8.47")

Very confortable library over mockito:
testImplementation 'org.mockito:mockito-inline:2.21.0'
testImplementation('com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0') {
exclude group: 'org.jetbrains.kotlin'
exclude group: 'org.mockito'
}
// Also works like a charm with instrumentation tests
androidTestImplementation 'org.mockito:mockito-android:3.5.13'
androidTestImplementation('com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0') {
exclude group: 'org.jetbrains.kotlin'
exclude group: 'org.mockito'
}

Related

Program type already present: android.support.v4.media.MediaBrowserCompat$CustomActionCallback

I completely new to Android Development and can't seem to resolve this error:
"Error: Program type already present: android.support.v4.media.MediaBrowserCompat$CustomActionCallback"
This is my dependencies:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.0-alpha1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.2'
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0-alpha1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0-alpha1'
implementation "android.arch.navigation:navigation-fragment:1.0.0-alpha01"
implementation "android.arch.navigation:navigation-ui:1.0.0-alpha01"
androidTestImplementation 'androidx.test:runner:1.1.0-alpha3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha3'
testImplementation 'junit:junit:4.12'
}
I've googled some and ended up on the developer page about "Resolve duplicate class errors", but I'm still not able to fix this. Help would be very much appriciated!
Option 1
Following worked for me
Add the following in your gradle.properties file
android.useAndroidX = true
android.enableJetifier = false
Option 2 (if above does't work)
Android studio -> Navigate -> Class
Check include non-project classes
Copy full class path android.support.v4.accessibilityservice.AccessibilityServiceInfoCompat
See where it is used. You may need to remove, one of them.
Option 3
you might be including package which is including modules as well so exclude the support-v4 module with following method
implementation ('org.eclipse.paho:org.eclipse.paho.android.service:1.0.2') {
exclude group: 'com.android.support', module:'support-v4'
}
You can analyze the conflicting modules using ./gradlew :YOURPROJECT:dependencies from a command line in your project repository.
Check especially your third party libraries for occurences of "com.android.support-":
Then exclude the conflicting modules from these dependencies like:
implementation ("com.jakewharton:butterknife:8.8.1") {
exclude group: 'com.android.support', module: 'support-v4'
exclude group: 'com.android.support', module: 'support-annotation'
exclude group: 'com.android.support', module: 'support-compat'
}
Im using flutter, and Im adding some native libraries in android, I tried the solutions posted here, but the trick for me was android.enableJetifier = true instead false
So, adding the following code to the gradle.properties, my apps are running:
android.useAndroidX = true
android.enableJetifier = true
if you still getting error after
# gradle.properties
android.useAndroidX = true
android.enableJetifier = false
then you probably forgot about main activity that calling android.support.v7.app.AppCompatActivity
change it to androidx.appcompat.app.AppCompatActivity
adding following plugins
cordova plugin add cordova-plugin-androidx
cordova plugin add cordova-plugin-androidx-adapter
solved the problem for me
At least for me the issue was with the implementation 'androidx.legacy:legacy-support-v4:1.0.0-alpha1' dependency. I went into the menu in Android Studio to create a Blank Fragment in Kotlin just to see what that would look like and the dependency above was added.
Once i removed that dependency the error went away.
Some of your existing dependencies are using older versions of support library, try this
implementation 'androidx.legacy:legacy-support-v4:1.0.0-alpha1' {
exclude group: 'com.android.support'
exclude module: 'support-v4'
}

Mockito+PowerMock gradle configuration

I need to use in my android instrumented tests mockito and powermock.
The main problem is that both of them have some problems with configuring it in gradle because of conflicts and other stuff.
Maybe somebody who has working configuration of .gradle file for mockito+powermock in android instrumented tests could share it?
This is my gradle configuration to use mockito and powerMock:
dependencies {
...
/**Power mock**/
testCompile "org.powermock:powermock-core:1.7.3"
testCompile "org.powermock:powermock-module-junit4:1.7.3"
testCompile "org.powermock:powermock-api-mockito2:1.7.3"
/**End of power mock **/
}
NOTE: I had to remove the mockito dependency in order to make it works:
//Remove this line
testImplementation "org.mockito:mockito-core:2.13.0"
Here is the configuration I am using and it's working perfectly fine.
after 1.7.0 powermock-api-mockito change to powermock-api-mockito2
testImplementation 'org.mockito:mockito-all:1.10.19'
testImplementation "org.powermock:powermock-module-junit4:2.0.7"
testImplementation "org.powermock:powermock-module-junit4-rule:2.0.7"
testImplementation "org.powermock:powermock-api-mockito2:2.0.7"
testImplementation "org.powermock:powermock-classloading-xstream:1.6.6"

Android Espresso testing 'Cannot resolve symbol 'InstrumentationRegistry''

I'm trying to import
import android.support.test.InstrumentationRegistry;
my build.gradle file
androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
androidTestCompile 'com.android.support.test:runner:0.2'
androidTestCompile 'com.android.support.test:rules:0.2'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
in default config:
defaultConfig {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
Is there a library I'm missing here? I'm trying to import InstrumentationRegistry but it doesn't recognise it!
Check what kind of test do you use.
InstrumentationRegistry used for Instrumented tests
that use emulator or device and they are placed in src/androidTest and use config androidTestCompile.
If you use Local unit tests for JVM from folder src/test you should use
config testCompile
testImplementation 'com.android.support.test:runner:1.0.2'
After that you can import InstrumentationRegistry, but you will get other errors at run-time.
try
compile 'com.android.support.test:runner:0.2'
instead of
testCompile 'com.android.support.test:runner:0.2'
it seems, com.android.support.test had been recently excluded from some other package (no clue which one), which also resulted in android.support.test.InstrumentationRegistryto be unknown; not excluding it from com.android.support.test:runner fixed the issue for me.
androidTestImplementation ("com.android.support.test:runner:1.0.2") {
// exclude group: "com.android.support.test"
exclude group: "com.android.support"
}
basically, androidTestImplementation needs to contain com.android.support.test once.
Another alternative - you can also add androidx.test:monitor dependency where the class InstrumentedRegistry is.
androidTestImplementation 'androidx.test:monitor:x.y.z'

Android unit test not mocked

I followed this guide but I am stuck with this error:
junit.framework.AssertionFailedError: Exception in constructor:
testSaveJson (java.lang.RuntimeException: Method put in
org.json.JSONObject not mocked. See
https://sites.google.com/a/android.com/tools/tech-docs/unit-testing-support
for details.
I modified by Gradle build like the guide says but it doesn't make a difference
testOptions {
unitTests.returnDefaultValues = true
}
JSON is bundled up with the Android SDK, so you'll just be hitting a stub. You can pull in a JSON jar, which will provide real objects to use.
To do this, you'll need to add this to your build.gradle:
testImplementation 'org.json:json:20140107'
Alternatively, you can download and include the jar.
testCompile files('libs/json.jar')
Note that the latest version of JSON is built for Java 8, so you'll need to grab 20140107
You may also need to clean and rebuild the project.
I think you trying to run tests with org.json.JSONObject which is part of Android Framework on pure jUnit.
From docs:
The android.jar file that is used to run unit tests does not contain any actual code - that is provided by the Android system image on real devices. Instead, all methods throw exceptions (by default).
We are aware that the default behavior is problematic when using classes like Log or TextUtils and will evaluate possible solutions in future releases.
You need to emulate Android environment you can use for this purpose Robolectric or InstrumentationTests
You need to add the following to the build.gradle:
android {
// ...
testOptions {
unitTests.returnDefaultValues = true
}
}
and
dependencies {
//...
testImplementation 'org.json:json:20180813'
}
Solution for the problem in if you're using Kotlin DSL:
testOptions {
unitTests.isReturnDefaultValues = true
}
testImplementation("org.json:json:20210307")
android {
testOptions {
unitTests.returnDefaultValues = true
} }
dependencies {
testImplementation libs.leakCanaryNoOp
testImplementation tests.jUnit
testImplementation tests.mockito
testImplementation(tests.mokitoKotlin) {
exclude group: "org.jetbrains.kotlin", module: "kotlin-stdlib"
exclude group: "org.jetbrains.kotlin", module: "kotlin-runtime"
exclude group: "org.jetbrains.kotlin", module: "kotlin-reflect"
exclude group: "org.mockito", module: "mockito-core"
}
testImplementation tests.powerMock
testImplementation tests.powerMockApiMockito
testImplementation (tests.robolectric) {
exclude group: 'org.robolectric', module: 'robolectric-resources:'
}
testImplementation (tests.robolectricShadowsSupport){
exclude group: 'org.robolectric', module: 'robolectric'
}
kaptTest libs.daggerCompiler
}

AndroidStudio/Gradle with powermock

I couldn't find any info on how to setup powermock with Android Studio/Gradle. Everything I've tried resulted in build exceptions.
Could anybody show a correct way to do it?
Thanks.
I'm posting in order to help future readers, you need to add these dependencies for powermock in AS
testImplementation 'junit:junit:4.12'
testImplementation 'org.powermock:powermock-api-mockito:1.6.2'
testImplementation 'org.powermock:powermock-module-junit4-rule-agent:1.6.2'
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.2'
testImplementation 'org.powermock:powermock-module-junit4:1.6.2'
Add the following lines to your dependencies{} block:
testCompile 'junit:junit:4.12'
testCompile 'org.powermock:powermock:1.6.5'
testCompile 'org.powermock:powermock-module-junit4:1.6.5'
And if you would like to use PowerMockito, add the following line:
testCompile 'org.powermock:powermock-api-mockito:1.6.5'
In the build script, add the following:
sourceSets {
unitTest {
java.srcDir file('*your test directory*') //for example: tests/java
}
}
android {
sourceSets {
instrumentTest.setRoot('*your root test directory*') //for example: tests
}
}
repositories {
mavenCentral()
}
dependencies {
testCompile 'junit:junit:4.11'
testCompile 'org.powermock:powermock-mockito-release-full:1.4.9'
}
Then, do gradle unitTest from the command line.
Hope that works. If it doesn't, post the output of the command line.
If you want to use more recent versions of Mockito, you can use something like this, which is adapted from the mockito 2 Powermock docs. Do make sure you use the right version of PowerMock for the given version of Mockito.
...
testCompile 'junit:junit:4.12'
testCompile "org.mockito:mockito-core:2.4.0"
testCompile 'org.powermock:powermock-module-junit4:1.7.0RC2',
'org.powermock:powermock-api-mockito2:1.7.0RC2'
// mockito
testImplementation 'org.mockito:mockito-core:2.4.0'
androidTestImplementation 'org.mockito:mockito-core:2.4.0'
// PowerMock
testImplementation 'org.powermock:powermock-core:1.7.0RC2'
testImplementation 'org.powermock:powermock-module-junit4:1.7.0RC2'
testImplementation 'org.powermock:powermock-api-mockito2:1.7.0RC2'
I have used same as #Bhargav used with some additional features added with it
code coverage for test case (if testCoverageEnabled is true, then it enable Jacoco tool)
unit test will test only your code and do not depend on any particular behaviour of Android platform by using (UnitTests.returnDefaultValues = true)
Add this marked lines in build.gradle to enable JUnit, PowerMockito, JaCoCo
My example compiled from all the other answers I could find, with latest versions at the time of writing:
app\build.gradle
dependencies {
testImplementation group: 'junit', name: 'junit', version: '4.13'
...
testImplementation group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.7'
testImplementation group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.7'
}
A test class where say Android Log class was static mocked.
import android.util.Log;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest({Log.class})
public class DateUtilsTest {
#BeforeClass
public static void beforeClass() {
PowerMockito.mockStatic(Log.class);
}
...
}

Categories

Resources