Is there any way I can Mock Static Function in Android using any Mocking Framework. Mockito can mock classes but is insuffiecient to mock Static functions.
Any help will be highly appreciated.
Thanks in Advance
Is there any way I can Mock Static Function in Android using any Mocking Framework. Mockito can mock classes but is insuffiecient to mock Static functions.
Any help will be highly appreciated.
Thanks in Advance
Mocking works by using the concepts of Object Orientation, Inheritance etc....
Basically by overriding certain methods & behaviour in objects / instances that look like real objects, because they are subclasses of these real objects.
In other words, the mocking part comes in overriding methods on instances.
It is not possible to override a static method (afaik).
Therefore mocking of static calls is not easy (if even possible).
As it turns out, I was wrong in my above statement that it is not possible.
I should have searched this site for duplicate questions. See below for some links to frameworks that claim to do this for you in some cases. Since they work with bytecode, I'm not sure they will work properly on Android (ymmv).
(thanks to Rohit for forcing me to reassess my beliefs)
Please try this instead: https://bintray.com/linkedin/maven/dexmaker-mockito-inline-extended
It helps me successfully mock the static method in the Android Instrumented Tests, but note that this feature requires running on a device with at least Android P.
Here is what I did:
Replace the androidTestImplementation 'org.mockito:mockito-android:2.28.0'
with androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito-inline-extended:2.28.0'
Then mock the static method like this:
static class StaticTrojan {
static String staticOpen() { return "horse"; }
}
@Test
public void testStubbingStaticMethod() {
MockitoSession session = mockitoSession().spyStatic(StaticTrojan.class).startMocking();
try {
when(StaticTrojan.staticOpen()).thenReturn("soldiers");
assertEquals("soldiers", StaticTrojan.staticOpen());
} finally {
session.finishMocking();
}
// Once the session is finished, all stubbings are reset
assertEquals("horse", StaticTrojan.staticOpen());
}
If you use Kotlin, then to mocking static functions you can connect the mockk library project:
androidTestImplementation "io.mockk:mockk-android:1.12.0"
Then you need to add a AndroidManifest.xml
to the androidTest directory if your tests are located in the application module.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="you.application.package">
<application
android:debuggable="true"
android:extractNativeLibs="true" />
</manifest>
Then you can mocking static functions using the following code:
import io.mockk.every
import io.mockk.mockkStatic
import io.mockk.unmockkStatic
import org.junit.Assert.assertEquals
import org.junit.Test
class TestMockingStaticFunction {
object StaticTrojan {
@JvmStatic
fun staticOpen(): String {
return "horse"
}
}
@Test
fun testMockingStaticFunction() {
assertEquals("horse", StaticTrojan.staticOpen())
mockkStatic(StaticTrojan::staticOpen)
val mockScope = every { StaticTrojan.staticOpen() } returns "solders"
assertEquals("solders", StaticTrojan.staticOpen())
unmockkStatic(StaticTrojan::staticOpen)
assertEquals("horse", StaticTrojan.staticOpen())
}
}
Library API allows you to comfortably mock the Kotlin objects, in the example above the object is used only to create a static function using @JvmStatic
annotation.
Attention! This approach uses JVMTI available in Android P starting from the API level 28. Your application can be written using a smaller API, but the tests you must run only on Android P devices or newer.