使用MockContentResolver进行查询会导致NullPointerException

时间:2014-03-16 21:27:52

标签: android nullpointerexception android-contentprovider android-contentresolver

我们有一个扩展ActivityInstrumentationTestCase2<CommentActivity>的JUnit测试类。测试(以及我们正在测试的课程)使用扩展CommentContentProvider的{​​{1}}来访问SQLite数据库,我们获得了ContentProvider [完整堆栈]在提供程序上运行查询时,跟踪以下内容。

我们实例化MockContentResolver,如下所示:

NullPointerException

稍后,在我们的测试中,当调用以下代码时,我们得到MockContentResolver mResolver; public void setUp() { super.setUp(); CommentContentProvider ccp = new CommentContentProvider(); mResolver = new MockContentResolver(); mResolver.addProvider(CommentContentProvider.AUTHORITY, ccp); }

NullPointerException

我们得到相同的结果,即使我们等待实例化Cursor mCursor = mResolver.query(Uri.parse(mUri), null, null, null, null); ,直到我们有一个被测活动的副本:

MockContentResolver

我们已确认mActivity = getActivity(); MockContentResolver mResolver = new MockContentResolver(mActivity); 不为空。

一位同事介入Android源代码(未安装在我们的系统上),发现错误的直接原因是mActivityfirst line of ContentProvider.enforceReadPermissionInner()上返回null。

我们看了this question,它原本看起来很相似,但我认为这完全是一个不同的问题。 This question也是问题的类似症状,但他们没有实例化getContext()。我们在实例化我们时遇到了问题。

这是我们获得的堆栈跟踪:

MockContentResolver

我们如何解决这个问题?

1 个答案:

答案 0 :(得分:8)

在测试内部依赖另一个内容提供程序写出一些元数据的内容提供程序时,我遇到了类似的问题。

首先,您可能最好使用ProviderTestCase2类,这将完成大部分工作,为您设置正在测试的提供程序。它可能会让你的生活变得更加容易。 (对我来说这还不够,因为它只会帮助你一个提供者,我需要两个。)

如果您无法做到这一点,这就是我的诀窍:

您的查询失败,因为您的提供商从未附加过上下文。您必须自己手动执行此操作 - 文档忘记提及。这样做:

public void setUp() {
    super.setUp();
    CommentContentProvider ccp = new CommentContentProvider();

    // Add this line to attach context:
    ccp.attachInfo(mActivity, null);

    mResolver = new MockContentResolver();
    mResolver.addProvider(CommentContentProvider.AUTHORITY, ccp);
}

我并不是100%确定要连接哪个上下文以使您的测试与世界其他地方隔离,ProviderTestCase2会建立一整套模拟上下文。如果您遇到问题,请查看RenamingDelegatingContextIsolatedContext,这些是ContentProviderTestCase2使用的问题。 (看看它的setUp()方法)。

希望这能帮到你!

相关问题