如何通过模拟其contentProvider来测试ListActivity,从而将测试与数据库隔离?

时间:2014-06-18 19:12:20

标签: android unit-testing mocking android-testing

我有一个ListView活动,它使用ContentProvider从SQLite数据库异步加载其数据。 我想测试这个活动,但我不想使用数据库。因为我希望它是可重复的。

我试图以这种方式模仿我的内容提供商:

public class MockRecipeContentProvider extends MockContentProvider{

private List<HashMap<String, String>> results;

@SuppressWarnings("nls")
public MockRecipeContentProvider(){
    super();

    this.results = new ArrayList<HashMap<String,String>>();

    //..populate this.result with som data
}

@Override
public Cursor query(Uri uri, String[] projection, String selection,
        String[] selectionArgs, String sortOrder) {

    MatrixCursor mCursor = new MatrixCursor(new String[] {RecipeTable.COLUMN_ID,
                                                          RecipeTable.COLUMN_NAME,
                                                          RecipeTable.COLUMN_INGREDIENTS,
                                                          RecipeTable.COLUMN_DIRECTIONS});

    for(int i =0; i<this.results.size(); i++){
        mCursor.addRow(this.getDataAtPosition(i));
    }
    return mCursor;
}
}       

这是我的测试用例:

public class MainActivityTest extends  ActivityUnitTestCase<MainActivity>{

private static final int INITIAL_NUM_ITEMS = 2;
private MainActivity mActivity;

public MainActivityTest() {
    super(MainActivity.class);

}

@Override
public void setUp() throws Exception{
    super.setUp();

    final MockContentResolver mockResolver = new MockContentResolver();
    MockRecipeContentProvider mockContentProvider = new MockRecipeContentProvider();

    mockResolver.addProvider(RecipeContentProvided.AUTHORITY, 
                             mockContentProvider);


    ContextWrapper mActivityContext = new ContextWrapper(
            getInstrumentation().getTargetContext()) {
        @Override
        public ContentResolver getContentResolver() {
            return mockResolver;
        }
    };

    this.setActivityContext(mActivityContext);
    startActivity(new Intent(mActivityContext, MainActivity.class), null, null);

    this.mActivity = getActivity();
}



public void testDisplayCorrectNumOfItems(){
    ListView lv = this.mActivity.getListView();

    assertTrue(lv.getCount()==INITIAL_NUM_ITEMS);
}

}

问题是没有调用MockRecipeContentProvider.query(),也没有调用RecipeContentProvider.query(),所以listView没有填充。 我做错了什么?

另一方面,我想编写一个集成测试用例,扩展ActivityInstrumentationTestCase2,我想测试生命周期等,但我已经读过如果你扩展ActivityInstrumentationTestCase2就不能进行模拟。那么,如何在不转发数据库的情况下编写这样的测试?

我不想使用数据库,因为我认为虽然我会使用RenamingDelegatingContext但它会导致测试根本不可重复,除非我可以删除测试数据库并重新创建它在setUp()方法中。这可以吗?

0 个答案:

没有答案