Android 如何使用内容解析器/提供者测试类?
我正在尝试测试查询内容解析器的类 我想使用Android 如何使用内容解析器/提供者测试类?,android,unit-testing,final,android-contentresolver,Android,Unit Testing,Final,Android Contentresolver,我正在尝试测试查询内容解析器的类 我想使用MockContentResolver和mockquery方法 问题是这种方法是最终的。我该怎么办?使用模拟框架?模仿其他班级?提前谢谢 public class CustomClass { private ContentResolver mContentResolver; public CustomClass(ContentResolver contentResolver) { mContentResolver =
MockContentResolver
和mockquery
方法
问题是这种方法是最终的。我该怎么办?使用模拟框架?模仿其他班级?提前谢谢
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()) {
//...
}
//..
}
}
阅读文档后,我能够编写
MockContentProvider
,实现相应游标的返回。然后,我使用addProvider
将此提供程序添加到MockContentResolver
下面是一个示例测试,它使用getContentResolver().query从内容提供程序返回模拟数据
它应该适用于任何内容提供商,只需稍作修改,但本例模拟了联系人内容提供商返回的电话号码
以下是一般步骤:
这个问题已经很老了,但人们可能仍然像我一样面临这个问题,因为没有太多关于测试这个问题的文档 对于我来说,对于依赖于内容提供者(来自android API)的测试类,我使用了ProviderTestCase2
public class ContactsUtilityTest extends ProviderTestCase2<OneQueryMockContentProvider> {
private ContactsUtility contactsUtility;
public ContactsUtilityTest() {
super(OneQueryMockContentProvider.class, ContactsContract.AUTHORITY);
}
@Override
protected void setUp() throws Exception {
super.setUp();
this.contactsUtility = new ContactsUtility(this.getMockContext());
}
public void testsmt() {
String phoneNumber = "777777777";
String[] exampleData = {phoneNumber};
String[] examleProjection = new String[]{ContactsContract.PhoneLookup.NUMBER};
MatrixCursor matrixCursor = new MatrixCursor(examleProjection);
matrixCursor.addRow(exampleData);
this.getProvider().addQueryResult(matrixCursor);
boolean result = this.contactsUtility.contactBookContainsContact(phoneNumber);
// internally class under test use this.context.getContentResolver().query(); URI is ContactsContract.PhoneLookup.CONTENT_FILTER_URI
assertTrue(result);
}
}
public class OneQueryMockContentProvider extends MockContentProvider {
private Cursor queryResult;
public void addQueryResult(Cursor expectedResult) {
this.queryResult = expectedResult;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
return this.queryResult;
}
}
公共类ContactsUtilityTest扩展了ProviderTestCase2{
私人接触性;
公共接触能力测试(){
super(OneQueryMockContentProvider.class,ContactsContract.AUTHORITY);
}
@凌驾
受保护的void setUp()引发异常{
super.setUp();
this.contactsutibility=新的contactsutibility(this.getMockContext());
}
公共无效测试SMT(){
字符串phoneNumber=“777”;
字符串[]exampleData={phoneNumber};
字符串[]examleProjection=新字符串[]{ContactsContract.PhoneLookup.NUMBER};
MatrixCursor MatrixCursor=新MatrixCursor(examleProjection);
addRow(exampleData);
this.getProvider().addQueryResult(matrixCursor);
布尔结果=this.contactsutibility.contactBookContainsContacts(电话号码);
//测试中的内部类使用此.context.getContentResolver().query();URI是ContactsContract.PhoneLookup.CONTENT\u FILTER\u URI
资产真实性(结果);
}
}
公共类OneQueryMockContentProvider扩展了MockContentProvider{
私有游标查询结果;
public void addQueryResult(游标预期结果){
this.queryResult=预期结果;
}
@凌驾
公共游标查询(Uri Uri、字符串[]投影、字符串选择、字符串[]selectionArgs、字符串排序器){
返回此.queryResult;
}
}
这是用Jenn Weingarten的答案写的。
需要注意的几件事:
-您的MockContentProvider
必须是公共的
-您必须在测试的类中使用方法this.getMockContext()
中的Context
,而不是this.getContext()
,否则您将访问设备中的模拟数据,而不是真实数据(在本例中为联系人)
-测试不能使用AndroidJUnit4 runner运行
-当然,测试必须作为android指令测试运行
-测试(authority)构造函数中的第二个参数必须和被测试类中查询的URI相同
-模拟提供程序的类型必须作为类参数提供
基本上,ProviderTestCase2使您能够初始化模拟上下文、模拟内容解析器和模拟内容提供者
我发现使用旧的测试方法比使用mockito和junit4为高度依赖android api的类编写本地单元测试要容易得多 我还没有使用Mockito,但对于内容提供商,您可以依赖Robolectric 您能提供完整的测试用例来测试联系人详细信息获取吗?这是一个不错的解决方案,但是自从API 24以来,
RenamingDelegatingContext
已被弃用。
@Override
public Context getContext(){
return new ContextWithMockContentResolver(super.getContext());
}
public class ContactsUtilityTest extends ProviderTestCase2<OneQueryMockContentProvider> {
private ContactsUtility contactsUtility;
public ContactsUtilityTest() {
super(OneQueryMockContentProvider.class, ContactsContract.AUTHORITY);
}
@Override
protected void setUp() throws Exception {
super.setUp();
this.contactsUtility = new ContactsUtility(this.getMockContext());
}
public void testsmt() {
String phoneNumber = "777777777";
String[] exampleData = {phoneNumber};
String[] examleProjection = new String[]{ContactsContract.PhoneLookup.NUMBER};
MatrixCursor matrixCursor = new MatrixCursor(examleProjection);
matrixCursor.addRow(exampleData);
this.getProvider().addQueryResult(matrixCursor);
boolean result = this.contactsUtility.contactBookContainsContact(phoneNumber);
// internally class under test use this.context.getContentResolver().query(); URI is ContactsContract.PhoneLookup.CONTENT_FILTER_URI
assertTrue(result);
}
}
public class OneQueryMockContentProvider extends MockContentProvider {
private Cursor queryResult;
public void addQueryResult(Cursor expectedResult) {
this.queryResult = expectedResult;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
return this.queryResult;
}
}