如何在Android上测试内容提供商

cha*_*och 11 sqlite junit android android-contentprovider

我正在尝试使用我的数据库进行测试ProviderTestCase2<T>.我可以看到正在创建测试数据库.因此我认为,测试内容提供商应该使用测试数据库.但是一旦我尝试任何针对MockContentResolver(或创建的newResolverWithContentProviderFromSql)的调用,我得到一个UnsupportedOperationException.这是MockContentResolver记录的正常行为.因此,我对ProviderTestCase2的目的有点不确定.

您如何测试您的内容提供商?

谢谢

Hen*_*ing 13

据我所知,设置模拟内容解析器并不是必需的 - 我可以监督它的情况(可能通过URI正确解析提供者,需要corect getType()工作的hings,但对我来说,它是足以做这样的事情:

package org.droidcon.apps.template.provider.test;

import org.droidcon.apps.template.provider.ProfileContract;
import org.droidcon.apps.template.provider.ProfileProvider;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.ProviderTestCase2;

public class ProfileProviderTest extends ProviderTestCase2<ProfileProvider> {

    public ProfileProviderTest() {
        super(ProfileProvider.class, ProfileProvider.class.getName());
    }

    protected void setUp() throws Exception {
        super.setUp();
    }


    /**
     * Very basic query test.
     * 
     * Prerequisites: 
     * <ul>
     * <li>A provider set up by the test framework
     * </ul>
     * 
     * Expectations: 
     * <ul>
     * <li> a simple query without any parameters, before any inserts returns a 
     * non-null cursor
     * <li> a wrong uri results in {@link IllegalArgumentException}
     * </ul>
     */
    public void testQuery(){
        ContentProvider provider = getProvider();

        Uri uri = ProfileContract.CONTENT_URI;

        Cursor cursor = provider.query(uri, null, null, null, null);

        assertNotNull(cursor);

        cursor = null;
        try {
            cursor = provider.query(Uri.parse("definitelywrong"), null, null, null, null);
            // we're wrong if we get until here!
            fail();
        } catch (IllegalArgumentException e) {
            assertTrue(true);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


ete*_*nay 6

我添加此条目,因为我认为它可以帮助想要测试其内容提供程序的程序员.

想象一下,您的内容提供商名为MyProvider,并且您有一个名为MyProviderContract的合同类,用于定义一些常量.

首先,您将编写一个名为MyProviderTestCase继承自的测试类ProviderTestCase2<MyProvider>.你必须定义一个将调用super构造函数的构造函数:

public MyProviderTestCase() {
    super(MyProvider.class, MyProviderContract.AUTHORITY);
}
Run Code Online (Sandbox Code Playgroud)

然后,而不是直接使用您的供应商(避免使用getProvider()为您的内容提供商的用户将不能直接访问它),使用getMockContentResolver()获得的内容解析器的引用,然后把这个内容分解的方法(query,insert等) .在下面的代码中,我将展示如何测试该insert方法.

public void testInsert() {
    Uri uri = MyProviderContract.CONTENT_URI;
    ContentValues values = new ContentValues();
    values.put(MyProviderContract.FIELD1, "value 1");
    values.put(MyProviderContract.FIELD2, "value 2");
    Uri resultingUri = getMockContentResolver().insert(uri, values);
    // Then you can test the correct execution of your insert:
    assertNotNull(resultingUri);
    long id = ContentUris.parseId(resultingUri);
    assertTrue(id > 0);
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用内容解析程序而不是内容提供程序直接添加任意数量的测试方法,就像内容提供商的用户一样.


emm*_*mby 3

扩展 ProviderTestCase2 以覆盖 getMockContentResolver() 并返回从 MockContentResolver 派生的您自己的类。

public class MyProviderTestCase2 extends ProviderTestCase2 {
    @Override
    public MockContentResolver getMockContentResolver () {
        return new MyMockContentResolver();
    }
}
Run Code Online (Sandbox Code Playgroud)

MyMockContentResolver 将需要重写您想要在 ContentProvider 中测试的任何方法。

然后,您应该能够在内容提供程序上运行任何您想要的测试,同时它被 ProviderTestCase2 隔离