gpt4 book ai didi

android - 如何使用内容解析器/提供者测试类?

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

我正在尝试测试查询内容解析器的类。

我想使用 MockContentResolver 和模拟 query 方法。

问题是这个方法是最终的。我应该怎么办?使用模拟框架?模拟其他类(class)?提前致谢。

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()) {
//...
}
//..
}
}

最佳答案

这是一个示例测试,它使用 getContentResolver().query 从内容提供者返回模拟数据。

它应该适用于任何内容提供者,只需进行一些修改,但此示例模拟从联系人内容提供者返回的电话号码

一般步骤如下:

  1. 使用 MatrixCursor 创建适当的游标
  2. 扩展 MockContentProvider 以返回创建的游标
  3. 使用 addProvider 和 setContentResolver 将提供程序添加到 MockContentResolver
  4. 将 MockContentResolver 添加到扩展的 MockContext
  5. 将上下文传递给被测类

因为查询是 final方法,所以您不仅需要模拟 MockContentProvider,还需要模拟 MockContentResolver。否则在查询方法中调用acquireProvider时会报错。

示例代码如下:

public class MockContentProviderTest extends AndroidTestCase{
public void testMockPhoneNumbersFromContacts(){
//Step 1: Create data you want to return and put it into a matrix cursor
//In this case I am mocking getting phone numbers from Contacts Provider
String[] exampleData = {"(979) 267-8509"};
String[] examleProjection = new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER};
MatrixCursor matrixCursor = new MatrixCursor(examleProjection);
matrixCursor.addRow(exampleData);

//Step 2: Create a stub content provider and add the matrix cursor as the expected result of the query
HashMapMockContentProvider mockProvider = new HashMapMockContentProvider();
mockProvider.addQueryResult(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, matrixCursor);

//Step 3: Create a mock resolver and add the content provider.
MockContentResolver mockResolver = new MockContentResolver();
mockResolver.addProvider(ContactsContract.AUTHORITY /*Needs to be the same as the authority of the provider you are mocking */, mockProvider);

//Step 4: Add the mock resolver to the mock context
ContextWithMockContentResolver mockContext = new ContextWithMockContentResolver(super.getContext());
mockContext.setContentResolver(mockResolver);

//Example Test
ExampleClassUnderTest underTest = new ExampleClassUnderTest();
String result = underTest.getPhoneNumbers(mockContext);
assertEquals("(979) 267-8509",result);
}

//Specialized Mock Content provider for step 2. Uses a hashmap to return data dependent on the uri in the query
public class HashMapMockContentProvider extends MockContentProvider{
private HashMap<Uri, Cursor> expectedResults = new HashMap<Uri, Cursor>();
public void addQueryResult(Uri uriIn, Cursor expectedResult){
expectedResults.put(uriIn, expectedResult);
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){
return expectedResults.get(uri);
}
}

public class ContextWithMockContentResolver extends RenamingDelegatingContext {
private ContentResolver contentResolver;
public void setContentResolver(ContentResolver contentResolver){ this.contentResolver = contentResolver;}
public ContextWithMockContentResolver(Context targetContext) { super(targetContext, "test");}
@Override public ContentResolver getContentResolver() { return contentResolver; }
@Override public Context getApplicationContext(){ return this; } //Added in-case my class called getApplicationContext()
}

//An example class under test which queries the populated cursor to get the expected phone number
public class ExampleClassUnderTest{
public String getPhoneNumbers(Context context){//Query for phone numbers from contacts
String[] projection = new String[]{ ContactsContract.CommonDataKinds.Phone.NUMBER};
Cursor cursor= context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, null, null, null);
cursor.moveToNext();
return cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
}
}

如果不想传入上下文:

如果你想让被测类中的 getContext() 返回它而不是传递它,你应该能够像这样在你的 android 测试中覆盖 getContext()

@Override
public Context getContext(){
return new ContextWithMockContentResolver(super.getContext());
}

关于android - 如何使用内容解析器/提供者测试类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6610437/

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