In my test how can I mock a class I wrote?
Here is my test code:
import android.support.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
#RunWith(AndroidJUnit4.class)
public class SampleTest {
#Mock
Sample mySample;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void shouldMockSample() {
verify(mySample, never()).neverCallMe();
}
}
Sample is just a dummy class.
public class Sample {
public void neverCallMe() {}
}
How do I get rid of this error?
java.lang.VerifyError: org/mockito/cglib/core/ReflectUtils at
org.mockito.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:167)
at
org.mockito.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at
org.mockito.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:217)
at
org.mockito.cglib.core.KeyFactory$Generator.create(KeyFactory.java:145)
at org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:117) at
org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:109) at
org.mockito.cglib.core.KeyFactory.create(KeyFactory.java:105) at
org.mockito.cglib.proxy.Enhancer.(Enhancer.java:70) at
org.mockito.internal.creation.cglib.ClassImposterizer.createProxyClass(ClassImposterizer.java:95)
at
org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:57)
at
org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:49)
at
org.mockito.internal.creation.cglib.CglibMockMaker.createMock(CglibMockMaker.java:24)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33) at
org.mockito.internal.MockitoCore.mock(MockitoCore.java:59) at
org.mockito.Mockito.spy(Mockito.java:1368)
at java.lang.reflect.Method.invokeNative(Native Method) at
java.lang.reflect.Method.invoke(Method.java:515) at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at
org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at
org.junit.runners.ParentRunner.run(ParentRunner.java:363) at
org.junit.runners.Suite.runChild(Suite.java:128) at
org.junit.runners.Suite.runChild(Suite.java:27) at
org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at
org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at
org.junit.runners.ParentRunner.run(ParentRunner.java:363) at
org.junit.runner.JUnitCore.run(JUnitCore.java:137) at
org.junit.runner.JUnitCore.run(JUnitCore.java:115) at
android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:54)
at
android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:228)
at
android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1741)
java.lang.NoClassDefFoundError:
org/mockito/internal/creation/cglib/ClassImposterizer$3 at
org.mockito.internal.creation.cglib.ClassImposterizer.createProxyClass(ClassImposterizer.java:95)
at
org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:57)
at
org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:49)
at
org.mockito.internal.creation.cglib.CglibMockMaker.createMock(CglibMockMaker.java:24)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33) at
org.mockito.internal.MockitoCore.mock(MockitoCore.java:59) at
org.mockito.Mockito.spy(Mockito.java:1368)
at java.lang.reflect.Method.invokeNative(Native Method) at
java.lang.reflect.Method.invoke(Method.java:515) at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at
org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at
org.junit.runners.ParentRunner.run(ParentRunner.java:363) at
org.junit.runners.Suite.runChild(Suite.java:128) at
org.junit.runners.Suite.runChild(Suite.java:27) at
org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at
org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at
org.junit.runners.ParentRunner.run(ParentRunner.java:363) at
org.junit.runner.JUnitCore.run(JUnitCore.java:137) at
org.junit.runner.JUnitCore.run(JUnitCore.java:115) at
android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:54)
at
android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:228)
at
android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1741)
I am using the following dependencies in my gradle file:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.1'
androidTestCompile 'com.android.support:support-annotations:22.2.1'
androidTestCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'org.objenesis:objenesis:2.1'
androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
androidTestCompile 'com.android.support.test:runner:0.3'
androidTestCompile 'com.android.support.test:rules:0.3'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2'
testCompile 'org.mockito:mockito-core:1.10.19'
testCompile 'org.hamcrest:hamcrest-library:1.3'
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.0'
}
Since version 2.6.+, Mockito added a new artifact that works for Android without the need of any other dependency (i.e. no need to import DexMaker anymore). (Reference)
Just use org.mockito:mockito-android as a dependency for your instrumented unit tests (androidTest). You would still use the usual org.mockito:mockito-core for your local unit tests.
Example:
dependencies {
...
testImplemenation 'org.mockito:mockito-core:2.7.15'
androidTestImplementation 'org.mockito:mockito-android:2.7.15'
...
}
By default, Mockito uses CGLib or ByteBuddy, both of which generate .class files. You're running on an Android device or emulator, so .class files won't help; you need .dex format instead.
Adjust your dependencies to use DexMaker, which will override Mockito's default and allow mocking in Android environments.
add these dependencies
androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("com.linkedin.dexmaker:dexmaker-mockito-inline:2.28.1")
testImplementation("junit:junit:4.13.2")
testImplementation("androidx.test:core:1.4.0")
testImplementation("org.mockito:mockito-android:4.2.0")
testImplementation("org.mockito:mockito-inline:4.2.0")
testImplementation("org.mockito:mockito-core:4.2.0")
and you can use mockito like this:
#RunWith(AndroidJUnit4::class)
class MainActivityTest {
#get:Rule
val composeTestRule = createComposeRule()
private lateinit var viewModel: HomeScreenViewModel
#Mock
private val sampleUseCase = mock(SampleUseCase::class.java)
#Before
fun setup() {
runBlockingTest {
`when`(sampleUseCase.invoke(anyInt(), anyString())).thenReturn(
NetworkDataState.Success(listOf(
SampleObject(id = 1),
SampleObject(id = 2),
SampleObject(id = 3),
))
)
viewModel = HomeScreenViewModel(
sampleUseCase
)
}
}
#Test
fun navigationTest() {
composeTestRule.setContent {
AppTheme {
MainScreen(
navController = rememberNavController(),
viewModel = viewModel
)
}
}
composeTestRule
.onNodeWithContentDescription("chips")
.performScrollToIndex(4)
}
}
Related
I am getting the below error on running my espresso test:
java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.
at androidx.test.platform.app.InstrumentationRegistry.getInstrumentation(InstrumentationRegistry.java:45)
at androidx.test.espresso.base.BaseLayerModule.provideTargetContext(BaseLayerModule.java:1)
at androidx.test.espresso.base.BaseLayerModule_ProvideTargetContextFactory.provideTargetContext(BaseLayerModule_ProvideTargetContextFactory.java:1)
at androidx.test.espresso.base.BaseLayerModule_ProvideTargetContextFactory.get(BaseLayerModule_ProvideTargetContextFactory.java:1)
at androidx.test.espresso.base.BaseLayerModule_ProvideTargetContextFactory.get(BaseLayerModule_ProvideTargetContextFactory.java:2)
at androidx.test.espresso.base.BaseLayerModule_ProvideDefaultFailureHanderFactory.get(BaseLayerModule_ProvideDefaultFailureHanderFactory.java:1)
at androidx.test.espresso.base.BaseLayerModule_ProvideDefaultFailureHanderFactory.get(BaseLayerModule_ProvideDefaultFailureHanderFactory.java:2)
at androidx.test.espresso.base.BaseLayerModule_ProvideFailureHanderFactory.get(BaseLayerModule_ProvideFailureHanderFactory.java:1)
at androidx.test.espresso.base.BaseLayerModule_ProvideFailureHanderFactory.get(BaseLayerModule_ProvideFailureHanderFactory.java:2)
at androidx.test.espresso.base.BaseLayerModule_FailureHandlerHolder_Factory.get(BaseLayerModule_FailureHandlerHolder_Factory.java:1)
at androidx.test.espresso.base.BaseLayerModule_FailureHandlerHolder_Factory.get(BaseLayerModule_FailureHandlerHolder_Factory.java:2)
at androidx.test.espresso.core.internal.deps.dagger.internal.DoubleCheck.get(DoubleCheck.java:6)
at androidx.test.espresso.DaggerBaseLayerComponent.failureHandler(DaggerBaseLayerComponent.java:1)
at androidx.test.espresso.DaggerBaseLayerComponent$ViewInteractionComponentImpl.viewInteraction(DaggerBaseLayerComponent.java:1)
at androidx.test.espresso.Espresso.onView(Espresso.java:1)
at com.example.espressotest.FirstTest.test1ChatId(FirstTest.java:51)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at android.support.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)
at android.support.test.internal.runner.junit4.statement.RunAfters.evaluate(RunAfters.java:61)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:527)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at android.support.test.runner.AndroidJUnit4.run(AndroidJUnit4.java:101)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:384)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189)
`
I have added the below dependencies in build.gradle
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'androidx.navigation:navigation-fragment:2.3.0'
implementation 'androidx.navigation:navigation-ui:2.3.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
testImplementation 'org.robolectric:robolectric:4.0.2'
testImplementation 'androidx.test:core-ktx:1.3.0'
testImplementation 'androidx.test.ext:junit-ktx:1.1.2'
androidTestCompile 'com.android.support:support-annotations:24.0.0'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestImplementation "com.android.support:support-annotations:27.1.1"
androidTestImplementation 'com.android.support.test:rules:1.0.2'
android {
defaultConfig {
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
}
testOptions {
unitTests.includeAndroidResources = true
}
}
}
I tried following the solution mentioned here AndroidX : No instrumentation registered! Must run under a registering instrumentation but it didn't work for me.
Can someone help me resolve it?
You need to fix your dependencies
testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
should be
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
I am trying to use okhttp3.mockwebserver.MockWebServer for some intrumented testing on Android. This is what I have in my build.gradle (:app) file for instrumented testing:
androidTestImplementation 'androidx.annotation:annotation:1.1.0'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestUtil 'androidx.test:orchestrator:1.3.0'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test:rules:1.3.0'
androidTestImplementation 'androidx.test:core:1.3.0'
androidTestImplementation 'org.mockito:mockito-android:2.7.22'
androidTestImplementation 'com.squareup.okhttp3:mockwebserver:4.9.0'
Here's my java file in andoidTest/java folder:
import android.content.Intent;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import org.junit.Rule;
import org.junit.Test;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
public class MainActivityTest {
MockWebServer server = new MockWebServer();
#Rule
public ActivityTestRule<MainActivity> activityRule
= new ActivityTestRule<>(MainActivity.class);
#Test
public void testNoSessionData() {
try {
server.enqueue(new MockResponse().setBody("[]").setResponseCode(200));
server.start(8080);
activityRule.launchActivity(
new Intent(
InstrumentationRegistry.getInstrumentation().getContext(),
MainActivity.class
).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
);
} catch (Exception e) {
ExceptionTracker.log(e);
}
}
and here's the exception I'm seeing:
java.lang.NoClassDefFoundError: Failed resolution of: Lokhttp3/internal/concurrent/TaskRunner$RealBackend;
at okhttp3.mockwebserver.MockWebServer.<init>(MockWebServer.kt:101)
at and.dev.cell.MainActivityTest.<init>(MainActivityTest.java:18)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:395)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189)
Caused by: java.lang.ClassNotFoundException: Didn't find class "okhttp3.internal.concurrent.TaskRunner$RealBackend" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/system/framework/android.test.mock.jar", zip file "/data/app/and.dev.cell.test-BTg7mf7fGT0rZNPUutH4Kg==/base.apk", zip file "/data/app/and.dev.cell-zdMzg_u88rFRy9yIIP8HqQ==/base.apk"],nativeLibraryDirectories=[/data/app/and.dev.cell.test-BTg7mf7fGT0rZNPUutH4Kg==/lib/x86, /data/app/and.dev.cell-zdMzg_u88rFRy9yIIP8HqQ==/lib/x86, /data/app/and.dev.cell.test-BTg7mf7fGT0rZNPUutH4Kg==/base.apk!/lib/x86, /data/app/and.dev.cell-zdMzg_u88rFRy9yIIP8HqQ==/base.apk!/lib/x86, /system/lib, /system/product/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
... 29 more
Verify that you have the same version of okhttp for all your libraries, if you are not sure you can force it with the next code:
resolutionStrategy {
force "com.squareup.okhttp3:okhttp:$okhttp3_version"
}
or adding explicitly in your application gradle file.
I have an Android Activity that implements an delegate interface which is called IMeetingRoomDelegate
interface IMeetingRoomDelegate {
fun onMeetingRoomFragmentClicked(homeFragment: MeetingRoomHomeFragment, meetingRoom: ParcelableMeetingRoomData)
}
I want to always assure that my Activity is always an implementation of IMeetingRoomDelegate.
How would I check this in Kotlin? I so far have this:
#RunWith(AndroidJUnit4::class)
class GivenTheMainActivityIsLoaded {
#get:Rule
val activityRule = ActivityTestRule<MainActivity>(MainActivity::class.java)
private lateinit var mainActivity: MainActivity
#Before
fun setup() {
this.mainActivity = activityRule.activity
}
#Test
fun thenThereShouldAlsoBeAnInstanceOfIMeetingRoomDelegatePresent() {
assertTrue(implementsInterface(this.mainActivity::class.java))
}
private fun implementsInterface(interf: Class<*>): Boolean {
return interf is IMeetingRoomDelegate
}
}
I've tried seeing what the issue is myself but the test runner is barely giving anything substantial away.
The error
java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:86)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertTrue(Assert.java:52)
at activities.GivenTheMainActivityIsLoaded.thenThereShouldAlsoBeAnInstanceOfIMeetingRoomDelegatePresent(MainActivitySpec.kt:54)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)
at androidx.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:527)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at androidx.test.runner.AndroidJUnit4.run(AndroidJUnit4.java:104)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:392)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189)
Tests ran to completion.
You could use the reified generics instead of asserting the reflections:
#Test
fun thenThereShouldAlsoBeAnInstanceOfIMeetingRoomDelegatePresent() {
assertTrue(this.mainActivity.implementsInterface())
}
private inline fun <reified T> T.implementsInterface(): Boolean {
return this is IMeetingRoomDelegate
}
The problem I have with this piece of code is that I can't add anything to the test class. Everything in TestModule can't be mocked.
I run my android test with AndroidJUnit4 and Mockito. We use Android X and Dagger lib.
problem inject object in test.
code
#RunWith(AndroidJUnit4.class)
#LargeTest
public class AppHelperTest {
#Inject
public AppHelper appHelper;
#Before
public void setup() {
Application application = (Application) InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext();
TestComponent component = DaggerTestComponent.builder().application(application).appModule(new TestModules()).build();
component.inject(this);
}
#Test
public void checkVersion_appHelper_Subscribed() {
verify(appHelper).checkVersion().test().assertSubscribed();
}
}
TestRunner MockitoException Mockito cannot mock this class: AppHelper
Underlying exception : java.lang.UnsupportedOperationException:
Cannot define class using reflection
at com.app.di.modules.TestModules.getAppHelper(TestModules.java:72)
at com.app.di.modules.TestModules_GetAppHelperFactory.getAppHelper(TestModules_GetAppHelperFactory.java:33)
at com.app.di.modules.TestModules_GetAppHelperFactory.get(TestModules_GetAppHelperFactory.java:25)
at com.app.di.modules.TestModules_GetAppHelperFactory.get(TestModules_GetAppHelperFactory.java:8)
at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
at com.app.di.DaggerTestComponent.injectAppHelperTest(DaggerTestComponent.java:450)
at com.app.di.DaggerTestComponent.inject(DaggerTestComponent.java:435)
at com.app.ui.helper.AppHelperTest.setup(AppHelperTest.java:46)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:76)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:104)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:392)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2252)
Caused by: java.lang.UnsupportedOperationException: Cannot define class using reflection
at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection$Dispatcher$Unavailable.defineClass(ClassInjector.java:819)
at net.bytebuddy.dynamic.loading.ClassInjector$UsingReflection.inject(ClassInjector.java:183)
at net.bytebuddy.dynamic.loading.ClassLoadingStrategy$Default$InjectionDispatcher.l
With Mockito version 3.2.0 we ship "native" Android support. To enable Android support, add the mockito-android library as dependency to your project. This artifact is published to the same Mockito organization and can be imported for Android as follows:
repositories {
jcenter()
}
dependencies {
testCompile "org.mockito:mockito-core:+"
androidTestCompile "org.mockito:mockito-android:+"
}
I can't initialize MockWebServer on androidTest folder. I've already added this line on my gradle
androidTestCompile('com.squareup.okhttp3:mockwebserver:3.6.0') {
exclude group: 'com.squareup.okio', module: 'okio'
exclude group: 'com.squareup.okhttp3', module: 'okhttp'
}.
I tried to follow the implementation from https://github.com/riggaroo/android-retrofit-test-examples. I've cloned the project, change the version of MockWebServer used by this example to the latest one and it still works fine but the implementation from my project still gives me same error.
java.lang.NoSuchMethodError: No static method initializeInstanceForTests()V in class Ld/a/a; or its super classes (declaration of 'd.a.a' appears in /data/app/com.agri.fma-2/base.apk)
at okhttp3.mockwebserver.MockWebServer.<clinit>(MockWebServer.java:101)
at com.agri.fma.activity.TestInputTenantActivity.setUp(TestInputTenantActivity.java:68)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at android.support.test.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:270)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1886)
Below, TestInputTenantActivity code
public class TestInputTenantActivity {
#Rule public IntentsTestRule<InputTenantActivity> activityTestRule =
new IntentsTestRule<>(InputTenantActivity.class, false, false);
#Inject InputTenantView view;
#Mock
SharedPreferenceManager sharedPreferenceManager;
private TestMainApplication app;
private MockWebServer mockWebServer;
#Before
public void setUp() throws Exception {
app = (TestMainApplication) InstrumentationRegistry.getInstrumentation()
.getTargetContext().getApplicationContext();
DaggerTestInputTenantComponent.builder().testAppComponent(app.getAppComponent())
.testInputTenantModule(new TestInputTenantModule())
.build().inject(this);
mockWebServer = new MockWebServer();
mockWebServer.start();
}
#Test
public void testEmptyTenant(){
activityTestRule.launchActivity(new Intent());
onView(withId(R.id.tenant)).perform(typeText(""));
onView(withId(R.id.action_next)).perform(click());
onView(withId(R.id.tenant)).check(matches(hasErrorText(app.getString(R.string.empty_tenant))));
intended((hasComponent(new ComponentName(getTargetContext(), LoginActivity.class))), times(0));
}
#Test
public void testTenantWithWhiteSpace(){
String errorMessage = String.format(
Locale.US,
app.getString(R.string.invalid_string_error),
"Tenant name");
activityTestRule.launchActivity(new Intent());
onView(withId(R.id.tenant)).perform(typeText(TENANT_WITH_WHITESPACE));
onView(withId(R.id.action_next)).perform(click());
onView(withId(R.id.tenant)).check(matches(hasErrorText(errorMessage)));
intended((hasComponent(new ComponentName(getTargetContext(), LoginActivity.class))), times(0));
}
#Test
public void testValidTenant(){
activityTestRule.launchActivity(new Intent());
onView(withId(R.id.tenant)).perform(typeText(VALID_TENANT));
onView(withId(R.id.action_next)).perform(click());
intended(hasComponent(new ComponentName(getTargetContext(), LoginActivity.class)));
}
#After
public void tearDown() throws Exception {
mockWebServer.shutdown();
}
}