gpt4 book ai didi

android - 使用 MockContentResolver 的查询导致 NullPointerException

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:21:08 26 4
gpt4 key购买 nike

我们有一个扩展ActivityInstrumentationTestCase2<CommentActivity> 的JUnit 测试类.测试(以及我们正在测试的类)使用 CommentContentProvider , 它扩展了 ContentProvider , 访问 SQLite 数据库,我们得到一个 NullPointerException [下面的完整堆栈跟踪] 在提供程序上运行查询时。

我们实例化一个 MockContentResolver如图:

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,我们也会得到相同的结果直到我们拥有被测 Activity 的副本:

mActivity = getActivity();
MockContentResolver mResolver = new MockContentResolver(mActivity);

我们已经验证mActivity不为空。

一位同事检查了 Android 源代码(未安装在我们的系统上),发现错误的近因是 getContext()first line of ContentProvider.enforceReadPermissionInner() 上返回 null .

我们看了一下this question最初看起来很相似,但我认为这完全是一个不同的问题。 This question也是问题的类似症状,但他们没有实例化他们的 MockContentResolver .我们在实例化我们的问题时遇到了问题。

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

java.lang.NullPointerException
at android.content.ContentProvider$Transport.enforceReadPermissionInner(ContentProvider.java:449)
at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:394)
at android.content.ContentProvider$Transport.query(ContentProvider.java:194)
at android.content.ContentResolver.query(ContentResolver.java:461)
at android.content.ContentResolver.query(ContentResolver.java:404)
at packagename.test.FooActivityTest.getNumCommentsForRecipient(FooActivityTest.java:84)
at packagename.test.FooActivityTest.testCommentEntryInternal(FooActivityTest.java:91)
at packagename.test.FooActivityTest.testCommentEntry1(FooActivityTest.java:108)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.access$000(InstrumentationTestCase.java:36)
at android.test.InstrumentationTestCase$2.run(InstrumentationTestCase.java:189)
at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:1719)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4998)
at java.lang.reflect.Method.invokeNative(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593)
at dalvik.system.NativeStart.main(Native Method)

我们如何解决这个问题?

最佳答案

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

首先,您最好使用 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() 方法)。

希望对你有帮助!

关于android - 使用 MockContentResolver 的查询导致 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22443259/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com