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

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

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

谢谢

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

 public class MyProviderTestCase2 extends ProviderTestCase2 { @Override public MockContentResolver getMockContentResolver () { return new MyMockContentResolver(); } } 

MyMockContentResolver将需要覆盖您要在ContentProvider中测试的任何方法。

然后,当ProviderTestCase2隔离内容提供程序时,您应该可以在内容提供程序上运行所需的任何测试

据我所知,设置模拟内容解析器并不是必需的 – 我可以监督它的情况(可能通过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 { public ProfileProviderTest() { super(ProfileProvider.class, ProfileProvider.class.getName()); } protected void setUp() throws Exception { super.setUp(); } /** * Very basic query test. * * Prerequisites: * 
    *
  • A provider set up by the test framework *
* * Expectations: *
    *
  • a simple query without any parameters, before any inserts returns a * non-null cursor *
  • a wrong uri results in {@link IllegalArgumentException} *
*/ 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); } } }

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

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

首先,您将编写一个名为MyProviderTestCase的测试类,该类inheritance自ProviderTestCase2 。 你必须定义一个将调用super构造函数的构造函数:

 public MyProviderTestCase() { super(MyProvider.class, MyProviderContract.AUTHORITY); } 

然后,不要直接使用您的提供程序(避免使用getProvider()因为内容提供程序的用户将无法直接访问它),请使用getMockContentResolver()获取对内容解析程序的引用,然后调用此内容解析程序的方法( queryinsert等)。 在下面的代码中,我将展示如何测试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); } 

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