How to test Activity/Fragment with ViewBinding generated classes? - android

I recently started fixing a test class for fragment, and the fragment got migrated to ViewBinding form Butterknife implementation.
The test started failing since then.
Now I have option to use Roboelectric with PowerMock / Roboelectric with Mockito.
So far I have tried multiple ways. None of them actually worked. Moreover I understood, version matching of these dependencies is a "thing".
I tried to refer these approaches: https://github.com/robolectric/robolectric/issues/5598 but no luck.
So here what I am using:
testImplementation 'org.robolectric:robolectric:4.6-alpha-1'
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0'
testImplementation 'org.mockito:mockito-inline:4.6.1'
testImplementation "org.powermock:powermock-module-junit4:2.0.2"
testImplementation "org.powermock:powermock-api-mockito2:2.0.2"
Any suggestion/help will be helpful regarding this.
Thanks in advance.

Related

How to use PowerMock with Mockito3.x?

I am trying to use PowerMock for the first time. Currently, my app is using Mockito 3.x. I tried to setup PowerMock with following test dependencies:
testImplementation 'org.powermock:powermock-api-mockito:1.6.6'
testImplementation 'org.powermock:powermock-module-junit4-rule-agent:2.0.0'
testImplementation 'org.powermock:powermock-module-junit4-rule:2.0.0'
testImplementation 'org.powermock:powermock-module-junit4:2.0.0'
But, this results in failing test cases with the following error:
java.lang.NoClassDefFoundError: org/mockito/MockitoAnnotations$Mock
After reading the PowerMock doc, it seems that PowerMockito is not compatible with Mockito 3.x. If this is not the case, please help me to set up the PowerMock with Mockito 3.x
According to #1049, mockito 3.x is now supported by Powermock.

In a Kotlin unit test, why does Android Studio show Mockito as unresolved reference EVEN THOUGH it compiles & tests pass?

Pretty weird problem: Mockito deps look broken even though they actually work.
Why does this happen and how to fix it?
The tooltip over those errors says "unresolved reference".
Some details:
These are unit tests (under app/src/test), not Android instrumentation tests.
This only happens when the test is Kotlin. In equivalent Java test, Mockito deps show up just fine in Android Studio.
To reiterate, even though Mockito stuff is shown in red, it still works: the test compiles and passes, both on the command line and in Android Studio.
In build.gradle, under dependencies:
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.19.0'
// ...
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.50"
(Also I have a file named org.mockito.plugins.MockMaker containing mock-maker-inline, so that Mockito works with final Kotlin classes.)
Edit: This shouldn't be relevant, but for Android instrumentation tests, there's also this. (I had some problems updating to Mockito 2 earlier, so sticking with 1.10.19 there.)
// Here keeping older Mockito for now
androidTestImplementation 'org.mockito:mockito-core:1.10.19'
// dexmaker needed for Mockito to work in androidTest
androidTestImplementation 'com.google.dexmaker:dexmaker:1.2'
androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.2'
Using Android Studio 3.5.3
What I've tried
Re-sync the project (build.gradle)
Run clean Gradle task inside AS
Close the project and open it again
Quit Android Studio completely and open it again
Update
I think this is related to several versions of Mockito being present in the project.
When I Cmd-click on the names shown in red, it takes me to sources in mockito-core-1.9.5-sources.jar; but when I Cmd-click on ArgumentMatchers or MockitoJUnitRunner, it takes me to mockito-core-2.19.0-sources.jar, the correct one.
I investigated with app:dependencies, and the only reference to Mockito 1.9.5 is through dexmaker-mockito.
+--- com.google.dexmaker:dexmaker-mockito:1.2
| +--- com.google.dexmaker:dexmaker:1.2
| \--- org.mockito:mockito-core:1.9.5 -> 1.10.19 (*)
But as dexmaker dependency is only for androidTest it shouldn't affect anything under test, right...? 🤔
Edit: indeed, the androidTest deps somehow confused Android Studio; commenting out all mockito and dexmaker deps in androidTestImplementation removed the faulty error highlights (but as mentioned, the different version was used for a reason).
In the end, Android Studio update fixed this.
Oh well, this was a bug in Android Studio: updating to latest version (3.6.2) fixed it.
The androidTestImplementation dependencies were conflicting with testImplementation ones; see updated question for details.

Using Androidx test dependencies in Robolectric instrumentation tests

I am having an issue with testImplementation and androidTestImplementationin build.gradle. I know that the former is used for unit tests while the latter for instrumentation tests.
Now, the problem is that Roboletric recommends using AndroidX ActivityScenario for launching activities and this class lives in androidx.test:rules. So to make ActivityScenario visible for unit tests, I will have to use testImplementation to declare androidx.test:rules dependency in build.gradle (e.g testImplementation 'androidx.test:rules:1.1.1').
What this implies is that androidx.test:rules classes won't be available for instrumentation tests.
Please, how do I resolve this issue? Do I have to declare a separate androidTestImplementation 'androidx.test:rules:1.1.1' for instrumentaion tests while keeping testImplementation 'androidx.test:rules:1.1.1' for unit tests?

More than one file was found with OS independent path 'mockito-extensions/org.mockito.plugins.MockMaker'

More than one file was found with OS independent path 'mockito-extensions/org.mockito.plugins.MockMaker' getting this error while adding
androidTestImplementation "org.mockito:mockito-inline:2.15.0"
in gradle to mock final class
For Android, you usually just want
androidTestImplementation "org.mockito:mockito-android:<latest-version>"
You especially don't want mockito-inline because it configures the wrong MockMaker (mock-maker-inline) instead of AndroidByteBuddyMockMaker which is the only one working on Android that is distributed by the Mockito project. If you need advanced capabilities or faster mocking, head over to the dexmaker project.
In my case I resolved this issue by removing dexmaker dependency from the build.gradle
So, I removed the below dependency
androidTestImplementation "com.linkedin.dexmaker:dexmaker-mockito:2.12.1"
and kept only the below Mockito dependency
androidTestImplementation "org.mockito:mockito-android:2.25.0"
Not sure if that your case, but it solves mine.
If you are using Koin dependency injector, I found the solution on this Github issue.
Try androidTestImplementation ("org.koin:koin-test:$koin_version") { exclude group: 'org.mockito' }
It worked for me, I hope this may help others in the future.
The only correct answer is PowerMockito does not support the Davik VM Android uses, it is meant for a standard JVM. So you can't use it with instrumented tests, only unit tests. I have heard there's a library called OpenDex that allows you to use PowerMockito even with Android but it seems a bit involved to setup and I haven't personally tried it.

Cannot resolve ActivityTestRule after upgrading dependencies. Unable to import ActivityTestRule

I have written instrumentation tests which was working fine, but now getting error cannot resolve ActivityTestRule error after upgrading dependencies to
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
I am using android support version 27.1.1
It is working fine with dependencies
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
In the most recent update of the Testing Support Library (2018-04-24), the "rules" dependency was apparently removed from the espresso-core. I'm not sure why this was done, but the release notes say this about the change:
Fixed espresso-core POM file to not pull in "rules" dependency, instead have espresso-intents POM pull it. This should be a NoOp change for developers since espresso-intents cannot be used without espresso-core.
You can fix this problem by adding the following dependency to app/build.gradle:
androidTestImplementation 'com.android.support.test:rules:1.0.2'
AndroidX Test includes another API,ActivityScenario that is currently in beta. This API works in a variety of testing environments and provides thread safety within the tests that use it. Consider using ActivityScenarioRule or ActivityScenario instead.
import androidx.test.ext.junit.rules.ActivityScenarioRule
ActivityScenarioRule(YourActivity::class.java)

Categories

Resources