如何使用内容解析器/提供者测试类?
我正在尝试测试查询内容解析器的类。
我想使用 MockContentResolver
和模拟 query
方法。
问题是这个方法是最终的。我应该怎么办?使用模拟框架?模拟其他类?提前致谢。
public class CustomClass {
private ContentResolver mContentResolver;
public CustomClass(ContentResolver contentResolver) {
mContentResolver = contentResolver;
}
public String getConfig(String key) throws NoSuchFieldException {
String value = null;
Cursor cursor = getContentResolver().query(...);
if (cursor.moveToFirst()) {
//...
}
//..
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
下面是一个使用 getContentResolver().query 从内容提供者返回模拟数据的示例测试。
它应该适用于任何内容提供程序,只需进行一些修改,但此示例模拟从联系人内容提供程序返回电话号码
以下是一般步骤:
因为 query 是一个最终方法,所以您不仅需要模拟MockContentProvider 也是 MockContentResolver。否则,在查询方法期间调用 acquireProvider 时会出现错误。
下面是示例代码:
如果您不想传入上下文:
如果您想让类中的 getContext() 返回它在测试中而不是传递它,你应该能够像这样在你的 android 测试中重写 getContext()
Here is an example test that returns mock data from a content provider using getContentResolver().query.
It should work for any content provider, with a few modifications, but this example mocks returning phone numbers from the Contacts content provider
Here are the general steps:
Because query is a final method, you need to mock not only MockContentProvider but also MockContentResolver. Otherwise you will get an error when acquireProvider is called during the query method.
Here is the example code:
If you don't want to pass context in:
If you wanted to have it returned by getContext() in the class under test instead of passing it in you should be able to override getContext() in your android test like this
这个问题已经很老了,但人们可能仍然会像我一样面临这个问题,因为没有太多关于测试这个问题的文档。
对我来说,为了测试依赖于内容提供者(来自android API)的类,我使用了ProviderTestCase2,
它是使用Jenn Weingarten的答案编写的。
有几点需要注意:
-您的
MockContentProvider
必须是公开的-您必须在测试类中使用
this.getMockContext()
方法中的Context
而不是this.getContext()
,否则您将访问不是模拟数据,而是来自设备的真实数据(在本例中为联系人)- 测试不得使用 AndroidJUnit4 运行程序运行
- 测试当然必须作为 Android 仪器测试运行
- 测试构造函数中的第二个参数(权威)必须与被测类中查询的 URI 相同
- 模拟提供程序的类型必须作为类参数提供
基本上 ProviderTestCase2 可以帮助您初始化模拟上下文、模拟内容解析器和模拟内容提供程序。
我发现使用旧的测试方法比尝试使用mockito和junit4为高度依赖于android api的类编写本地单元测试要容易得多。
This question is pretty old but people might still face the issue like me, because there is not a lot of documentation on testing this.
For me, for testing class which was dependent on content provider (from android API) I used ProviderTestCase2
It's written by using Jenn Weingarten's answer.
Few things to note:
-your
MockContentProvider
must be public-you must use
Context
from methodthis.getMockContext()
instead ofthis.getContext()
in your class under test, otherwise you will access not mock data but real data from device (in this case - contacts)-Test must not be run with AndroidJUnit4 runner
-Test of course must be run as android instrumented test
-Second parameter in constructor of the test (authority) must be same compared to URI queried in class under test
-Type of mock provider must be provided as class parameter
Basically ProviderTestCase2 makes for you initializing mock context, mock content resolver and mock content provider.
I found it much more easier to use older method of testing instead of trying to write local unit test with mockito and junit4 for class which is highly dependent on android api.
下面是一个关于如何使用 mockk 库和 Kotlin 存根 ContentResolver 的示例。
注意:如果您在模拟器中运行此测试,此测试似乎不起作用,在具有 API 23 的模拟器中失败,并出现此错误
“java.lang.ClassCastException:android.database.MatrixCursor 无法转换为 java.lang。布尔值”
。澄清了这一点,让我们这样做。具有来自 Context 对象的扩展,即
val Context.googleCalendars: List>
,此扩展会过滤日历,日历名称不以“@google.google.com”结尾。 com”,我正在使用此 AndroidTest 测试此扩展的正确行为。是的,您可以从此处下载存储库。
Here is an example about how to stub a ContentResolver with mockk Library and Kotlin.
NOTE: this test seems that is not working if you run this in an emulator, fails in an emulator with API 23 with this error
"java.lang.ClassCastException: android.database.MatrixCursor cannot be cast to java.lang.Boolean"
.Clarified that, lets do this. Having an extension from Context object, that is called,
val Context.googleCalendars: List<Pair<Long, String>>
, this extension filters calendars witch calendar name doesn't ends with "@google.com", I am testing the correct behavior of this extension with this AndroidTest.Yes you can download the repo from here.
阅读文档后,我能够编写
MockContentProvider
来实现适当游标的返回。然后我使用addProvider
将此提供程序添加到MockContentResolver
中。After reading docs I was able to write
MockContentProvider
that implemented return of appropriate cursors. Then I added this provider toMockContentResolver
usingaddProvider
.我还没有使用过 Mockito,但对于内容提供商来说,您可以依赖 Robolectric。 https://github.com/juanmendez/jm_android_dev/blob/master/16.observers/00.magazineAppWithRx/app/src/test/java/ContentProviderTest.java
I haven't used Mockito yet, but for content providers, you can rely on Robolectric. https://github.com/juanmendez/jm_android_dev/blob/master/16.observers/00.magazineAppWithRx/app/src/test/java/ContentProviderTest.java