AndroidStudio/Gradle with powermock - android

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);
}
...
}

Related

Duplicate class org.hamcrest.BaseDescription found in modules jetified-hamcrest-core-1.3.jar

Android studio 3.6
app/build.gradle:
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'com.azimolabs.conditionwatcher:conditionwatcher:0.2'
// Espresso framework
androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_version"
androidTestImplementation "androidx.test.espresso:espresso-intents:$espresso_version"
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espresso_version"
androidTestImplementation 'org.hamcrest:hamcrest-junit:2.0.0.0'
// UI Automator framework
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
androidTestImplementation 'com.squareup.okhttp3:mockwebserver:3.8.0'
// for test fragments
debugImplementation 'androidx.fragment:fragment-testing:1.2.0-rc02'
testImplementation 'junit:junit:4.12'
testImplementation 'com.nhaarman:mockito-kotlin-kt1.1:1.5.0'
in gradle.properties:
android.useAndroidX=true
android.enableJetifier=true
Here my Espresso instrumentation test:
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.hamcrest.text.MatchesPattern
import org.junit.runner.RunWith
#RunWith(AndroidJUnit4::class)
class FeedbackActivityTransportTest {
#Test
fun buttonSend_click_checkRequest() {
val request = mockServer.takeRequest();
assertEquals("POST", request.method)
assertThat(
request.body.toString(),
MatchesPattern.matchesPattern("(\"feedback.*\\\"type\\\":2\"))")
)
}
But I get error:
Duplicate class org.hamcrest.BaseDescription found in modules jetified-hamcrest-core-1.3.jar (org.hamcrest:hamcrest-core:1.3) and jetified-java-hamcrest-2.0.0.0.jar (org.hamcrest:java-hamcrest:2.0.0.0)
Duplicate class org.hamcrest.BaseMatcher found in modules jetified-hamcrest-core-1.3.jar (org.hamcrest:hamcrest-core:1.3) and jetified-java-hamcrest-2.0.0.0.jar (org.hamcrest:java-hamcrest:2.0.0.0)
Duplicate class org.hamcrest.Condition found in modules jetified-hamcrest-core-1.3.jar (org.hamcrest:hamcrest-core:1.3) and jetified-java-hamcrest-2.0.0.0.jar (org.hamcrest:java-hamcrest:2.0.0.0)
Duplicate class org.hamcrest.Condition$1 found in modules jetified-hamcrest-core-1.3.jar (org.hamcrest:hamcrest-core:1.3) and jetified-java-hamcrest-2.0.0.0.jar (org.hamcrest:java-hamcrest:2.0.0.0)
The exclusion of junit and giving the priority to Hamcrest will disable the oppotunity to perform unit tests with JUnit! That is why you would get an error in Android studio: Cannot resolve '#Before' or '#Test' while doing unit tests. The correct way to go will be replacing the Hamcrest with JUnit!
Place this code to build.gradle on app level:
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute module('org.hamcrest:hamcrest-core:1.1') with module('junit:junit:4.10')
}
}
I think this problem happened when you add a dependency (as your
situation Hamcrest and another dependency, library, Jar files, etc... is
using Hamcrest too! but with another version.
If you force your Hamcrest dependency in app Gradle like below might solve your problem:
configurations.all {
resolutionStrategy {
force 'org.hamcrest:hamcrest-junit:2.0.0.0'
}
}
After apply if you get the same error try to exclude like this:
configurations { compile.exclude group: "junit", module: "junit" }

How to set up Mockito for Kotlin and 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'
}

AndroidJUnit4.class not found on Instrumentation tests

I'm having trouble with AndroidJunit4.class import.
I created the test class in the androidTest/java/ folder but it seems that the class is not found.
Even if I force the right import it still doesn't work. ( import android.support.test).
#RunWith(AndroidJunit4.class)
public class RandomTest {
}
Here is my gradle :
defaultConfig {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
dependencies {
compile "com.android.support:support-annotations:23.4.0"
compile "com.android.support:appcompat-v7:23.4.0"
compile 'cat.ereza:customactivityoncrash:1.5.0'
testCompile 'junit:junit:4.12'
androidTestCompile 'junit:junit:4.12'
androidTestCompile('com.android.support.test:runner:0.5')
androidTestCompile('com.android.support.test:rules:0.5')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2')
androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.2')
androidTestCompile('com.android.support.test.espresso:espresso-intents:2.2.2')
testCompile('com.android.support.test:runner:0.5')
testCompile('com.android.support.test:rules:0.5')
testCompile('com.android.support.test.espresso:espresso-core:2.2.2')
testCompile('com.android.support.test.espresso:espresso-contrib:2.2.2')
testCompile('com.android.support.test.espresso:espresso-intents:2.2.2')
testCompile 'org.mockito:mockito-core:1.10.19'
testCompile "org.robolectric:robolectric:3.1.1"
}
Weird thing is that I can find AndroidJunit4 file in my project, but in its parent AndroidJunit4ClassRunner, AndroidRunnerParams class is not resolved even if I also can find the file in my Project.
Comment out the annotation
//#RunWith(AndroidJunit4.class)
In Android Studio, choose "Build > Rebuild Project"
Get the annotation back in again
#RunWith(AndroidJunit4.class)
ALT-ENTER -> Import class

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'

importing correct AssertThat method for Robolectric Test

I am attempting to run the test from Robolectric.org's Writing Your First Test page. The test in question looks like this:
#Test
public void clickingLogin_shouldStartLoginActivity() {
WelcomeActivity activity = Robolectric.setupActivity(WelcomeActivity.class);
activity.findViewById(R.id.login).performClick();
Intent expectedIntent = new Intent(activity, WelcomeActivity.class);
assertThat(shadowOf(activity).getNextStartedActivity()).isEqualTo(expectedIntent);
}
I get this compile error: Cannot resolve method 'assertThat(android.content.Intent).
The two possibilities I see for importing this method are org.hamcrest.MatcherAssert.assertThat and org.junit.Assert.assertThat, neither of which have a single-argument assertThat method as is being used in this Robolectric test.
My app's build.gradle has these dependencies:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.android.support:design:23.1.0'
testCompile "org.robolectric:robolectric:3.0"
testCompile 'junit:junit:4.12'
}
What framework/library is this test using?
It is neither junit or hamcrest assertion API. I think it is Android AssertJ or just AssertJ:
testCompile 'org.assertj:assertj-core:1.7.1'
follow the following and the issue should go away. Put the first line in you gradle build file
testCompile 'org.mockito:mockito-core:1.9.5'
testCompile 'junit:junit:4.12'
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
public class SomethingTest {
#Test
public void testSomething() {
assertThat(true, 1>1);
}
}
this link should provide more details also
Android Studio and Robolectric

Categories

Resources