在 activity 的 onCreate() 之前调用测试意图 - Espresso

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

我正在调用 intent 在 Activity 的 onCreate()

中打开画廊

在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" );
    }

这是我的测试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);

    }
}

这是我在 logCat

中得到的日志
E/---: test_selectImageForOcr: before1
E/---: test_selectImageForOcr: 1
E/---: test_selectImageForOcr: before2
E/---: test_selectImageForOcr: 2
E/---: test_selectImageForOcr: 3

我想启动一个 activity,因为我在选择图像后在此 activity 中进行另一个 UI 测试。所以保持 launchActivity 为 true

但是我遇到了这个异常

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.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)

我尝试了什么:

  1. 我试着让它成为一个单独的测试
  2. 我试图在 @Before 方法中调用 test_selectImageForOcr 但得到了同样的错误

此外,我需要在测试成功后关闭图像选择器。感谢任何帮助。


编辑

我找到了为什么会这样

当我在意图中设置 setType("image/*"); 时,我遇到了这个问题。如果我删除此类型,则测试将通过并且图像选择器也会关闭。这个问题有解决办法吗?

哦,那是我的错误。由于@SuppressLint()我无法识别这个

我需要按照此警告设置类型和 URI 都这样

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