androidandroid-intentandroid-espressoandroid-intent-chooser

call test intent before activity's onCreate() - Espresso


I am calling intent to open the gallery in Activity's onCreate()

this method is called in onCreate()

 @SuppressLint("IntentReset")
    private void requestForPickImage() {
        Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        i.setType("image/*");
        startActivityForResult(i, SELECT_PICTURE_REQUEST_CODE);
        Log.e("---", "test_selectImageForOcr: 2" );
    }

this is my Test Class

@RunWith(AndroidJUnit4.class)
@LargeTest
public class F_SelectImageForOcrActivityUnitTest {

    @Rule
    public GrantPermissionRule permissionRule =
            GrantPermissionRule.grant(android.Manifest.permission.READ_EXTERNAL_STORAGE,
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
    @Rule
    public IntentsTestRule<SelectImageToOcrActivity> mActivity =
            new IntentsTestRule<SelectImageToOcrActivity>(SelectImageToOcrActivity.class, true, true) {
                @Override
                protected void beforeActivityLaunched() {
                    super.beforeActivityLaunched();
                    Intents.init();
                    Log.e("---", "test_selectImageForOcr: before1");
                    test_selectImageForOcr();
                    Log.e("---", "test_selectImageForOcr: before2");
                }

                @Override
                protected void afterActivityFinished() {
                    Log.e("---", "test_selectImageForOcr: 3");
                    intended(expectedIntent);
                    Log.e("---", "test_selectImageForOcr: 4");
                    Intents.release();
                    super.afterActivityFinished();
                }
            };
    private Matcher<Intent> expectedIntent;

    @Before
    public void init() {

    }

    public void test_selectImageForOcr() {
        expectedIntent = AllOf.allOf(
                hasAction(Intent.ACTION_PICK),
                hasData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI),
                hasType("image/*")
        );

        ActivityResult picker = createPicker();
        Log.e("---", "test_selectImageForOcr: 1");
        intending(expectedIntent).respondWith(picker);
    }

    @Test
    public void testStart() {
        Espresso.onView(ViewMatchers.withId(R.id.btn_scan)).check(matches(isDisplayed())).perform(ViewActions.click());
    }

    private ActivityResult createPicker() {
        Resources resources = ApplicationProvider.getApplicationContext().getResources();
        Uri imageUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
                resources.getResourcePackageName(R.mipmap.ic_launcher) + '/' +
                resources.getResourceTypeName(R.mipmap.ic_launcher) + '/' +
                resources.getResourceEntryName(R.mipmap.ic_launcher));

        Intent resultData = new Intent();
        resultData.setData(imageUri);
        resultData.setType("image/*");

        return new ActivityResult(
                Activity.RESULT_OK, resultData);

    }
}

here is the log I get in logCat

E/---: test_selectImageForOcr: before1
E/---: test_selectImageForOcr: 1
E/---: test_selectImageForOcr: before2
E/---: test_selectImageForOcr: 2
E/---: test_selectImageForOcr: 3

I would like to launch an activity because I have another UI testing in this activity after picking an image. So keep launchActivity to true

But I am getting this exception

junit.framework.AssertionFailedError: Wanted to match 1 intents. Actually matched 0 intents.

IntentMatcher: (has action: is "android.intent.action.PICK" and has data: is <content://media/external/images/media> and has type: is "image/*")

Matched intents:[]

Recorded intents:
-Intent { act=android.intent.action.MAIN flg=0x14000000 cmp=com.my.app/com.my.app.camera.SelectImageToOcrActivity } handling packages:[[com.my.app]])
-Intent { act=android.intent.action.PICK typ=image/* } handling packages:[[com.google.android.apps.photos]])
    at junit.framework.Assert.fail(Assert.java:50)
    at androidx.test.espresso.intent.VerificationModes$Times.verify(VerificationModes.java:80)
    at androidx.test.espresso.intent.Intents.internalIntended(Intents.java:348)
    at androidx.test.espresso.intent.Intents$3.run(Intents.java:206)
    at androidx.test.espresso.intent.Intents$PropogatingRunnable.run(Intents.java:226)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:2223)
    at android.os.Handler.handleCallback(Handler.java:907)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7478)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:941)

What I tried:

  1. I tried to make it a separate test
  2. I tried to call test_selectImageForOcr in @Before method but getting the same error

Also, I need to close the image picker after test success. Any help is appreciated.


Edit

I found why this is happening

when i set setType("image/*"); in the intent that time I am getting this issue. if I remove this type than the test get passed and also image picker get closed. Is there any solution on this issue?


Solution

  • Oh, that's my mistake. Due to @SuppressLint() I can't recognize this

    I need to set Type & URI both like this as per this warning

    enter image description here

    Intent i = new Intent(Intent.ACTION_PICK);
    i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");