cta*_*mor 5 android nullpointerexception android-contentresolver android-contentprovider
我们有一个扩展的JUnit测试类ActivityInstrumentationTestCase2<CommentActivity>.测试(以及我们正在测试的类)使用CommentContentProvider扩展ContentProvider来访问SQLite数据库,并且NullPointerException在提供程序上运行查询时,我们得到了[下面的完整堆栈跟踪].
我们实例化一个MockContentResolver,如下所示:
MockContentResolver mResolver;
public void setUp() {
super.setUp();
CommentContentProvider ccp = new CommentContentProvider();
mResolver = new MockContentResolver();
mResolver.addProvider(CommentContentProvider.AUTHORITY, ccp);
}
Run Code Online (Sandbox Code Playgroud)
稍后,在我们的测试中,当调用以下代码时,我们得到一个NullPointerException:
Cursor mCursor = mResolver.query(Uri.parse(mUri), null, null, null, null);
Run Code Online (Sandbox Code Playgroud)
即使我们等待实例化,MockContentResolver直到我们有一个被测活动的副本,我们也会得到相同的结果:
mActivity = getActivity();
MockContentResolver mResolver = new MockContentResolver(mActivity);
Run Code Online (Sandbox Code Playgroud)
我们已经确认mActivity不是空的.
一位同事介入Android源代码(未安装在我们的系统上),发现错误的最直接原因是在ContentProvider.enforceReadPermissionInner()getContext()的第一行返回null .
我们看了一下这个看起来很相似的问题,但我认为这完全是一个不同的问题.
这个问题也是问题的类似症状,但他们没有实例化他们的问题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)
Run Code Online (Sandbox Code Playgroud)
我们如何解决这个问题?
在测试内部依赖另一个内容提供程序写出一些元数据的内容提供程序时,我遇到了类似的问题.
首先,您可能最好使用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);
}
Run Code Online (Sandbox Code Playgroud)
我并不是100%确定要连接哪个上下文来保持测试与世界其他地方隔离,ProviderTestCase2建立一整套模拟上下文.如果您有问题,看RenamingDelegatingContext和IsolatedContext,这些都是那些ContentProviderTestCase2用途.(看看它的setUp()方法).
希望这对你有所帮助!
| 归档时间: |
|
| 查看次数: |
1520 次 |
| 最近记录: |