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.
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 writing the AndroidJUnit4 test case for my Broadcast Receiver class , In which there is Runtime permission for the Location and Phone State to execute some piece of code. What i need that i need to give the Runtime permission by using the GrantPermissionRule .
Please check the below exception which i am getting now
I/TestRunner: started: testOnReceive(com.xxx.xxxxx.receiver.MyClassTest)
I/UiAutomationShellCmd: Requesting permission: pm grant com.xxxxx.test android.permission.ACCESS_FINE_LOCATION
E/GrantPermissionCallable: Permission: android.permission.ACCESS_FINE_LOCATION cannot be granted!
E/TestRunner: failed: testOnReceive(com.xxxx.xxx.receiver.MyClassTest)
----- begin exception -----
E/TestRunner: junit.framework.AssertionFailedError: Failed to grant permissions, see logcat for details
at junit.framework.Assert.fail(Assert.java:50)
at androidx.test.runner.permission.PermissionRequester.requestPermissions(PermissionRequester.java:111)
at androidx.test.rule.GrantPermissionRule$RequestPermissionStatement.evaluate(GrantPermissionRule.java:128)
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.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:154)
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:2084)
----- end exception -----
I/TestRunner: finished: testOnReceive(com.xx.xxxxx.receiver.MyClassTest)
junit.framework.AssertionFailedError: Failed to grant permissions, see logcat for details
at junit.framework.Assert.fail(Assert.java:50)
at androidx.test.runner.permission.PermissionRequester.requestPermissions(PermissionRequester.java:111)
at androidx.test.rule.GrantPermissionRule$RequestPermissionStatement.evaluate(GrantPermissionRule.java:128)
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.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:154)
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:2084)
And Please check my code in which I am using the GrantPermissionRule like below
import android.content.Context;
import android.content.Intent;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.GrantPermissionRule;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* MyClass Tester.
*
* #author <Authors name>
* #version 1.0
* #since <pre>Nov 5, 2020</pre>
*/
#RunWith(AndroidJUnit4.class)
public class MyClassTest {
private Context context;
private MyClass test;
#Rule public GrantPermissionRule permissionRule = GrantPermissionRule.grant(
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.READ_PHONE_STATE);
#Before
public void before() throws Exception {
context = InstrumentationRegistry.getInstrumentation().getTargetContext();
test = new MyClass();
System.out.print(getClass().getSimpleName() + " test start");
}
#After
public void after() throws Exception {
System.out.print(getClass().getSimpleName() + " test end");
}
/**
* Method: onReceive(Context context, Intent intent)
*/
#Test
public void testOnReceive() throws Exception {
//TODO: Test goes here...
if (SdkAppHelper.getInstance(context).isPermissionsAllowed()) {
test.onReceive(context, new Intent().setAction(SdkAppConstants.ACTION_START_1));
test.onReceive(context, new Intent().setAction(SdkAppConstants.ACTION_UPLOAD_11111_DATA_MANUALLY));
test.onReceive(context, new Intent().setAction(SdkAppConstants.ACTION_INITIALIZE_DEVICE_ID));
}
}
}
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've tried today the new android testing support lib. I need the write external storage permission for my tests so I've created the following test with the new GrantPermissionRule.
ExternalDirTest.java
#Rule
public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule.grant(Manifest.permission.WRITE_EXTERNAL_STORAGE);
#Test
public void test() throws IOException {
Application.getApplication().createDir();
}
Application.java
public void createDir() throws IOException {
new File(Environment.getExternalStorageDirectory() + "/test").createNewFile();
}
Officially I get the permission (visible in the app settings). Nevertheless I get the following exception:
java.io.IOException: Permission denied
at java.io.UnixFileSystem.createFileExclusively0(Native Method)
at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:280)
at java.io.File.createNewFile(File.java:948)
at test.app.directory.Application.createDir(EarApplication.java:253)
at test.app.directory.ExternalDirTest.test(ExternalDirTest.java:24)
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.rule.GrantPermissionRule$RequestPermissionStatement.evaluate(GrantPermissionRule.java:109)
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:58)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:369)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1932)
If I test the code manual it works perfectly.
Has someone facing the same problem or is it maybe a bug in the library itself?
Should now be fixed in version 1.0.2-alpha2
See https://issuetracker.google.com/issues/64389280
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)
}
}