Android 集成测试:如何使用 Expresso 意图模拟 onActivityResult 意图的 ClipData

Android Integration Test: How to mock ClipData of intent of the onActivityResult using the Expresso intent

我正在使用 Kotlin 开发 Android 应用程序。我正在使用 Expresso 框架为我的应用程序编写集成测试。现在,我正在努力模拟 onActivityResult 回调意图的 ClipData。我正在使用 Expresso 框架的 expresso-intent 来模拟意图。

下面是我的onActivityResult回调方法的实现。

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        Log.i(TAG, "Start handleGalleryActivityResult")
        if (data?.clipData?.itemCount == null) {
            return
        }

        if (data?.clipData?.itemCount as Int > 0) {
            Log.i(TAG, "handleGalleryActivityResult: clipData count is greater than zero")
            for (i in 0 until data?.clipData?.itemCount as Int) {
                Log.i(TAG, "Processing index ${i}")
                if (data?.clipData?.getItemAt(i)?.uri != null) {
                    val file: File = File(data?.clipData?.getItemAt(i)?.uri?.path)
                    Log.i(TAG, "Picked gallery file ${data?.clipData?.getItemAt(i)?.uri?.path}")
                } else {
                    Log.i(TAG, "Picked gallery file at index ${i} is null")
                }
            }
        }
    }

正如您在 onActivityResult 回调方法中看到的,我正在检索意图的 clipData。

我正在编写一个模拟返回意图的测试,如下所示。

@Test fun filesAreUploadedToServerWhenPickedUpFromGallery() {
        this.launchActivityWithIntent()
        val resultData = Intent()
        val result = Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)
        intending(IntentMatchers.hasAction(Intent.ACTION_PICK)).respondWith(result)
        onView(withId(R.id.camera_image_btn_gallery)).perform(click())

        //the rest of the code goes here
    }

正如您在我的代码中看到的那样,我正在模拟这样返回的意图。

intending(IntentMatchers.hasAction(Intent.ACTION_PICK)).respondWith(result)

我的问题是如何将剪辑数据传递给模拟它的意图?

ClipData 对象创建为

  1. 创建 ClipDescriptionClipData.Item 对象

    val clipDescription = ClipDescription("Dummy", arrayOf(ClipDescription.MIMETYPE_TEXT_PLAIN))
    
    val uri = Uri.parse("http://www.google.com");
    
    val clipItem = ClipData.Item(uri)
    
  2. 创建 ClipData 对象并将其设置为意图对象:

    val _clipData = ClipData(clipDescription, clipItem)
    
    resultData.clipData = _clipData
    

您可以使用 addItem as _clipData.addItem(clipItem). You can use other constructors and method of ClipDescription and ClipData.Item 类 添加更多项目以添加更多数据。

或者,您可以创建实际的模拟对象,并根据您的模拟框架为相同使用的对象模拟相应的方法。