8

我正在InstrumentationTestCase对我的应用程序的一个组件进行单元测试。

该组件将数据持久化到内部存储并用于Context::fileList();检索持久化的文件。

我遇到以下问题:在应用程序(在设备上)中使用此方法效果很好。但是当我尝试使用(Android-)单元测试(也在设备上)时,InstrumentationTestCase我得到了一个NullPointerException内部fileList()方法。我深入研究了 android 源代码,发现getFilesDir() (请参阅此处的源代码)返回 null 并导致此错误。

重现的代码如下:

public class MyTestCase extends InstrumentationTestCase
{   
    public void testExample() throws Exception
    {
        assertNotNull(getInstrumentation().getContext().getFilesDir()); // Fails
    }
}

我的问题是:这种行为是有意的吗?我能做些什么来规避这个问题?我使用InstrumentationTestCase正确还是应该使用不同的东西?

我发现了这个问题,但我不确定这是否涵盖了我遇到的相同问题。

4

2 回答 2

10

我认为您将测试数据与测试应用程序分开是正确的。

您可以通过执行以下命令为应用程序Null创建files目录来解决问题Instrumentation

adb shell
cd /data/data/<package_id_of_instrumentation_app>
mkdir files

您只能在模拟器或有根设备上执行上述操作。

然后从你的问题中测试不会失败。我做到了,还上传了名为 dir 的文件tst.txtfiles以下所有测试均成功:

assertNotNull(getInstrumentation().getContext().getFilesDir());
assertNotNull(getInstrumentation().getContext().openFileInput("tst.txt"));
assertNotNull(getInstrumentation().getContext().openFileOutput("out.txt", Context.MODE_PRIVATE));

但我认为向测试项目提供数据更方便的方法是使用assets测试项目,您可以在其中简单地保存一些文件并打开它们:

assertNotNull(getInstrumentation().getContext().getAssets().open("asset.txt"));

或者,如果您想将一些测试结果保存到文件中,您可以使用ExternalStorage

File extStorage = Environment.getExternalStorageDirectory();
assertNotNull(extStorage);
于 2013-01-22T22:11:10.393 回答
1

@Blackbelt 在他的评论中提到使用getTargetContext()而不是getContext(). 我错过了评论,几个小时后,试图弄清楚如何从 Android 仪器测试中找出 Realm.init(),我发现我需要来自getTargetContext()...的上下文(一路上,我试图context.filesDir.mkdirs()

package com.github.ericytsang

import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Test

class InstrumentedTest {

    private val context = InstrumentationRegistry.getInstrumentation().targetContext

    @Test
    fun can_mkdirs() {
        assert(context.filesDir.mkdirs())
    }
}
于 2020-01-10T06:21:27.927 回答