かんたんContentProviderテスト
概要
ContentProviderをRobolectric + Mockitoでテストを行う
Daoパターンの例
public class StorageDao {
private final Context mContext;
public StorageDao(Context context) {
mContext = context;
}
public Book getBook(int id) {
try (Cursor cursor = mContext.getContentResolver()
.query(StorageContracts.URI, null , StorageContracts.Colomns._ID + "=?"
, new String[]{String.valueOf(id)}, null)) {
if (cursor != null && cursor.moveToFirst()) {
String title = cursor.getString(cursor.getColumnIndex(StorageContracts.Colomns.TITLE));
String author = cursor.getString(cursor.getColumnIndex(StorageContracts.Colomns.AUTHOR));
return new Book(title, author);
}
}
return null;
}
}
一度は見たこと・書いたことがあるパターンかと思います。
では、これをMockitoとRobolectricを使ってテストを書いてみると、
public class StorageDaoTest {
StorageDao sut;
@Mock
MockContentProvider mockContentProvider;
@Before
public void setUp() throws Exception {
MockitoAnnotation.initialize(this);
sut = new StorageDao(RuntimeEnviroment.application);
ShadowContentResolover.register(StorageContracts.AUTHORITY, mockContentProvider);
}
@Test
public void getBook() {
// setup
MatrixCursor mockCursor = new MatrixCursor(new String[]{
StorageContracts.Colomns.TITLE,
StorageContracts.Colomns.AUTHOR
});
mockCursor.addRow(new Object[]{"白の闇", "ジョゼ・サラマーゴ"});
when(mockContentProvider.query(xxx,xxxx,xxx)).thenReturn(mockCursor);
// execute
Book actual = sut.getBook(1);
// verify
assertThat(actual.title, is("白の闇"));
assertThat(actual.author, is("ジョゼ・サラマーゴ"));
}
}
何度か試行錯誤しテストを書いていて現状のこの書き方に落ち着きました。
肝になるのはContentProviderをモックオブジェクトにしたところです。
こうしておくことでテストごとにContentProviderを継承して作る必要もなく、
テストに応じて好きに値を返すことができるので楽です。