ContentProvider 测试——分离生产和测试数据

ContentProvider testing - separating production and test data

我已经开始为我的内容提供商编写一个简单的测试。问题是当我 运行 使用生产数据进行测试时。如何确保从我的实时应用程序数据中使用单独的测试数据?

@RunWith(AndroidJUnit4.class)
public class MyContentProviderTest extends ProviderTestCase2<MyContentProvider>{
    public MyContentProviderTest() {
        super(MyContentProvider.class, MyContentProvider.AUTHORITY);
    }

    @Override
    protected void setUp() throws Exception {
        setContext(InstrumentationRegistry.getContext());
        //have also tried with setContext(InstrumentationRegistry.getTargetContext());
        super.setUp();
    }

    @Test
    public void insertTest(){
        ContentResolver contentResolver = getContext().getContentResolver();
        assertNotNull(contentResolver);

        contentResolver.insert(MyContentProvider.uri,createContentValues());
        Cursor cursor = contentResolver.query(MyContentProvider.uri, Database.ALL_COLUMNS,
             null, null, null);

        assertNotNull(cursor);

        // the test fails here because along with the row inserted above, there are also many more rows of data from using my app normally (not while under test).
        assertEquals( 1, cursor.getCount());

        //todo: verify cursor contents
        cursor.close();
    }

    ContentValues createContentValues(){
        ContentValues cv = new ContentValues();
        cv.put(Database.COLUMN_DATETIME, LocalDateTime.now().format(Util.DATE_FORMAT));
            /* ... etc */
        return cv;
    }
}

should I be using a different URI?

是的。您的测试代码正在影响您的生产供应商。您需要您的测试代码来命中您单独的测试提供者,并且需要它自己的权限字符串(并且从那里开始,Uri)。

新应用程序开发的典型方法是从 applicationId:

生成权限字符串
<provider
    android:name="MyContentProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true" />

你的权限字符串,在Java中为Uri构造,变为BuildConfig.APPLICATION_ID+".provider"。这要求您使用 Gradle 进行构建(例如,通过 Android Studio)或者在您使用的任何构建系统中具有等效的工具。

您的测试代码将获得 a separate testApplicationId automatically,或者您可以根据需要在 Gradle 中覆盖它。为生产和测试使用单独的应用程序 ID 意味着您有单独的内部存储,并且让您的代码始终引用正确的提供程序(通过应用程序 ID-specific 权限)意味着您的测试代码将使用测试提供程序和测试构建的内部存储,您的生产代码将使用生产提供程序和生产构建的内部存储。