Mockito mocks run actual Android code in Lollipop or greater - android

So I have a Database class that has a dependency that extends SQLOpenHelper and I am testing using Android instrumented tests and Mockito to mock dependencies. We are noticing that Mockito isn't actually mocking the implementations when doing Mockito.mock(class) instead the actual code is running and throwing null pointer exceptions as we would expect. On API 19 devices the tests run as expected and the mocks work correctly.
Does anyone have any suggestions or things to try? I've tried real devices and emulators with similar results. Could this be a Mockito issue, or a dex-maker issue? I haven't found any information while searching for it.
After some more testing any class I mock with Mockito actually just uses the implementation. Here are my dependencies
androidTestCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
Note: This is also in a library module if that makes any difference.

So getting rid of our old Mockito dependencies and dexmaker and using the new: Mockito-android
Fixed our issues

Related

Sonar coverage is showing lesser than the actual

I have written test cases using JUnit and PowerMockito. IntelliJ IDEA is showing 100% coverage for lot many classes but Sonar is showing just 19%
I am using following versions:
PowerMockito: 2.0.2
JUnit: 4.12
Jacoco: 0.8.5
Sonar: 7.3
i have gone through multiple posts but nothing solved this issue.
This sounds like you're running into the issue that Powermock replaces the Jacoco annotation during its instrumentation, so Jacoco has nothing to report against. You may be able to change the instrumentation type to overcome this, but it's currently a know limitation when using Powermock.

JUnit5 not generating test-result TEST-*.xml that JUnit4 used to

When I used JUnit4 in my projects it seemed that each time a test ran, it would generate a TEST-*.xml report in app/build/test-result. Jenkins would use these XML reports to display failing and passing tests on each build.
I've replaced JUnit4 with JUnit5 with the following in build.gradle:
testImplementation "org.junit.jupiter:junit-jupiter-api:5.3.2"
When running tests with JUnit 5, I'm no longer seeing these TEST-*.xml files being generated. As soon as I drop back to JUnit4, they are.
Is this no longer available in JUnit5 or is there something I have to set on each test in order to get these XML reports?
Found the solution. In order for the XML reports to be generated for each test you need to include the following in your build.gradle:
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.2'
As well as:
tasks.withType(Test) {
useJUnitPlatform()
}
This other post may also be of use to others: JUnit5 integration tests with Gradle 4.6

Tests not running properly - Android

I'm facing a problem when running tests on my project. I'm using JUnit, Mockito and PowerMock.
I have a test class which I can run from Android Studio and works well (6 out of 6 working). But, if instead of doing it from AS i use the command ./gradlew test three of them are failing with the error:
java.lang.NoClassDefFoundError at MyTestsClass.java:166
Searching that line I can see that's calling a method (so I suppose the error is not exactly there but inside the call, somewhere).
How can it be failing from the command and working from AS? What's the difference between this two? What could it be causing that error?
It could be because of your dependencies.
You don't have them defined on the test it won't compile. For example:
// Needed to compile
compileOnly 'com.madgag.spongycastle:prov:1.54.0.0'
// Needed to compile tests
testImplementation 'com.madgag.spongycastle:prov:1.54.0.0'
Could it be?

Robolectric + Mockito

Trying to build android unit tests using Robolectric. Everytime I need to mock a method that belongs to my project it becomes slightly heavy to create a Shadow class. I think using Mockito in such cases would be much easier and lighter.
But when I try to use Mockito methods I get an error java.lang.IllegalArgumentException: dexcache == null (and no default could be found; consider setting the 'dexmaker.dexcache' system property)
In order to fix this I believe the dexcache property needs to be set by calling
System.setProperty("dexmaker.dexcache",getInstrumentation().getTargetContext().getCacheDir().getPath());
But I don't know getInstrumentation can be called while in Robolectric. Pls suggest a recommended approach to mock the methods of my Project in Robolectric.
You can use Mockito with Robolectric; however, you need to make sure you're adding the "normal" Mockito dependency, and not the Mockito-Android or dexmaker dependency.
Mockito works by generating classes; on desktop JREs such as your unit test environment, that means generating Java CLASS files, but on Android devices and emulators that means generating DEX files. However, Mockito will opportunistically use DexMaker if it exists on the classpath, even when running outside of an emulator as Robolectric unit tests do. Adjust your dependencies to ensure that dexmaker is not included, which will avoid any problems with dexmaker or dexcache.
A good way to separate your thinking about Robolectric and Mockito is
Mockito: Mock and verify your Java classes / non Android framework dependencies
Robolectric: Provides the TestRunner and working Android Framework elements where needed, e.g. Intent, Context
Build.gradle dependencies
dependencies {
...
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.0'
testCompile 'org.mockito:mockito-core:1.10.19'
}
Robolectric test runner
#RunWith(RobolectricTestRunner.class)
public class ExampleUnitTest {
#Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
Happy testing!

Confused about testCompile and androidTestCompile in Android Gradle

I'm new to testing world and even more to Android testing world. While doing research on Robolectric that aids with tests on android one thing confuses me the most. Sometimes on the web I see people using testCompile keyword in dependencies of the gradle build script when referencing Robolectric while others use androidTestCompile. Certainly both can't be valid?
Can somebody explain the difference between the both and which of these should be the one used when using Robolectric?
Simply testCompile is the configuration for unit tests (those located in src/test) and androidTestCompile is used for the test api (that located in src/androidTest). Since you are intending to write unit tests, you should use testCompile.
Update: The main distinction between the two is the test sourceset runs in a regular Java JVM, whereas the androidTest sourceset tests run on an Android device (or an emulator).
To answer your question - Use testCompile for robolectric
why, because robolectric runs on the JVM mocking all the android device behaviour.
testCompile and androidTestCompile are "by convention" android folders which gradle uses while running tasks provided by android plugin.
androidTestDebug picks tests from androidTest folder,
testDebug picks tests from test folder,
Again these are only by convention folders you can give source sets for these configurations
Note: espresso is such an awesome library try to move away from robolectric :)
//unit testing
testCompile 'junit:junit:4.12'
The above code is a dependency of JUnit 4 in build.gradle file in android studio.
You see that it has testCompile, beacuse JUnit runs on JVM and does not require a device or emulator to run. That also means that JUnit tests will not require the application context to run and if they require we would need to "MOCK" them.
//Insturmented Unit Testing
androidTestCompile('com.android.support.test:runner:0.5', {
exclude group: 'com.android.support', module: 'support-annotations'
})
Now we see androidTestCompile here, because this time we intend to use the device or emulator for tests, that is Instrumentation testing. For beter clarification I would suggest to read from developer.android.com
To add Dependency for JVM testing or Unit testing (testing those rely only on java environment, we don’t need any android environment).
We Use testCompile directive. Example:
dependencies {
testCompile gradleTestKit()
}
To add Dependency for Instrumentation test (Those testing mainly rely on Android environment), we use the androidTestCompile directive.

Categories

Resources