如何使用Espresso意图存根选择图像意图?

Shi*_*til 10 java android android-intent android-testing android-espresso

这是我第一次使用espresso意图,我按照Android测试项目中提供的IntentsBasicSamle但没有解决.

在我的应用程序中,我有一个活动,用户选择多个图像然后返回的图像显示在gridview中,现在通过使用espresso意图我想模拟这个而不去实际的图像选择器并每次返回一些指定的图像.

没有错误,但在我运行测试时仍会打开图像选择器窗口.我觉得我做错了,但我没有得到它是如何工作的.

我正在测试使用apk.

这就是照片选择器的调用方式

应用代码

这就是我调用选择图像的方式Intent和结果在onActivityResult中处理.

if (ApiUtils.checkApiLevel(18)) {
        //API18+
        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
    }
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent,      getActivity().getString(R.string.fragment_image_selection_select_picture)), 1);
Run Code Online (Sandbox Code Playgroud)

测试代码

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

private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.company.recorder.RecorderActivity";
private static Class<? extends Activity> activityClass;
private ServiceValidatorIdlingResource serviceValidatorIdlingResource;

static {
    try {
        activityClass = (Class<? extends Activity>) Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
    }
}

/**
 * Change espresso default view idling time
 * so that test can wait for long time
 */
@Before
public void registerWaitService() {
    EspressoSolo.setIdlingResourceTimeout(30);

    Instrumentation.ActivityResult result = createImageCaptureActivityResultStub();

    // Stub the Intent.
    intending(hasAction(Intent.ACTION_GET_CONTENT)).respondWith(result);

   //For API 18 and above
    intending(hasAction(Intent.EXTRA_ALLOW_MULTIPLE)).respondWith(result);

    //intending(not(isInternal())).respondWith(result);
}

private Instrumentation.ActivityResult createImageCaptureActivityResultStub() {
    // Put the drawable in a bundle.
    Bundle bundle = new Bundle();
    Uri imageUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
            InstrumentationRegistry.getTargetContext().getPackageName()+ '/' +
            InstrumentationRegistry.getTargetContext().getResources().getResourceTypeName(R.drawable.abc_ic_menu_copy_mtrl_am_alpha) + '/' +
            InstrumentationRegistry.getTargetContext().getResources().getResourceEntryName(R.drawable.abc_ic_menu_copy_mtrl_am_alpha) );

    Parcelable parcelable = (Parcelable)imageUri;

    ArrayList<Parcelable> parcels = new ArrayList<>();
    parcels.add(parcelable);

    bundle.putParcelableArrayList(Intent.EXTRA_STREAM, parcels);

    // Create the Intent that will include the bundle.
    Intent resultData = new Intent();
    resultData.putExtras(bundle);

    // Create the ActivityResult with the Intent.
    return new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData);
}

@Rule
public IntentsTestRule<?> mIntentsRule = new IntentsTestRule<>(
        activityClass);


/**
 * In this test images are taken during the recording
 * add the images taken during the recording through add photos card
 * displayed after recording is stopped.
 *
 * @throws Exception
 */
@Test
public void testAddImagesFromPhotosCard() throws Exception {

    onView(withId(Recorder.getId("recorderpage_record"))).perform(click());

    Log.d("called", "other package");
    IdlingResource idlingResource0 = new RecordingWaitIdlingResource(5000);
    Espresso.registerIdlingResources(idlingResource0);

    Log.d("called", "other package");
    onView(withId(Recorder.getId("card_topText"))).perform(click());
    Espresso.unregisterIdlingResources(idlingResource0);
    onView(withId(Recorder.getId("recorderpage_stop"))).perform(click());
    //Log.d("called", "other package");
    IdlingResource idlingResource2 = new RecordingWaitIdlingResource(2000);
    Espresso.registerIdlingResources(idlingResource2);
    onView(withId(Recorder.getId("recorderpage_statustext")))
            .perform(click());
    Espresso.unregisterIdlingResources(idlingResource2);

    onView(withId(Recorder.getId("pager"))).perform(swipeLeft());

    onData(allOf()).onChildView(withId(Recorder.getId("recordsOverflow"))).
            atPosition(0).perform(click());

    IdlingResource idlingResource3 = new RecordingWaitIdlingResource(2000);
    Espresso.registerIdlingResources(idlingResource3);
    onData(allOf()).onChildView(withId(Recorder.getId("recordsOverflow"))).
            atPosition(0).perform(click());
    Espresso.unregisterIdlingResources(idlingResource3);
    onView(withText("Add an image")).perform(click());

    Instrumentation.ActivityResult result = createImageCaptureActivityResultStub();
    intending(toPackage("com.android.documentsui")).respondWith(result);

     /* I actually dont know which preinstalled app is opened by intent, I saw this com.android.documentsui, also tried with photos and gallery package names */

    intending(toPackage("com.android.documentsui.DocumentsActivity")).respondWith(result);

    intending(hasAction(Intent.ACTION_GET_CONTENT)).respondWith(result);

    //Now click on add images
    onView(withId(Recorder.getId("menu_fragment_imagewizard_selection_add"))).perform(click());

    //Just waits for 2seconds
    IdlingResource idlingResource4 = new RecordingWaitIdlingResource(2000);
    Espresso.registerIdlingResources(idlingResource4);
    onView(withText("Add images")).perform(click());
    Espresso.unregisterIdlingResources(idlingResource4);

}
}
Run Code Online (Sandbox Code Playgroud)

Shi*_*til 5

最后,这对我有用,发布了我的答案

Bundle bundle = new Bundle();
    ArrayList<Parcelable> parcels = new ArrayList<>();
    Intent resultData = new Intent();
    Uri uri1 = Uri.parse("file://mnt/sdcard/img01.jpg");
    Parcelable parcelable1 = (Parcelable) uri1;
    parcels.add(parcelable1);
    bundle.putParcelableArrayList(Intent.EXTRA_STREAM, parcels);
    // Create the Intent that will include the bundle.
    resultData.putExtras(bundle);

    intending(not(isInternal())).respondWith(new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData));
Run Code Online (Sandbox Code Playgroud)

权限

 @Rule public GrantPermissionRule permissionRule = GrantPermissionRule.grant(android.Manifest.permission.YOUR_PERMISSION; 
Run Code Online (Sandbox Code Playgroud)