正在尝试对使用 Realm 的项目进行单元测试。我存根了 realm 方法来测试我自己的代码,并发现了 RealmQuery 的问题。我想测试一个对象是否被 (1( 添加到 Realm 数据库;(2(可以检索;(3( 如果该对象的 set 属性与我期望的匹配。以下是我的 setup(( 和测试的部分内容。
我如何在setup((中存根一个领域数据库(someList是全局的&List<>(
SomeRealmObject some1;
some1.setId(1);
some1.setName("some1");
SomeRealmObject some2;
some2.setId(2);
some2.setName("some2");
someList = new ArrayList<SomeRealmObject>();
someList.add(some1);
someList.add(some2);
我如何在 setup(( 中存根复制到 Realm (添加函数(
when(mockRealm.copyToRealm).then(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
SomeRealmObject some = (SomeRealmObject) args[0];
userList.add(user);
return user;
}
});
我如何在 setup(( 中存根 RealmQuery(搜索函数(
RealmQuery someRealmQuery = someRealmQuery(); //followed mockito example on github
when(mockRealm.where(SomeRealmObject.class)).thenReturn(someRealmQuery);
when(realmQuery.equalsTo(anyString, anyInt).thenReturn(someRealmQuery);
when(realmQuery.findFirst()).then(findFirstAnswer);
问题从这里开始。我需要 realmQuery.equalsTo(...( 将其参数传递给链中的下一个方法。我认为这是必要的(但我可能是错的(,因为我应该测试以下两种方法:findFirst(( 和 findAll((。有什么想法吗?
我如何在 setup(( 中存根查找第一((
Answer findFirstAnswer = new Answer(){
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
String key = args[0].toString(); //Let's just use an Id search for
int id = (int) args[1]; //an example.
for(int count = 0; someList.get(count) != null; count++){
if(someList.get(count).getId == id){
return someList.get(count);
}
return null; //test will fail, someRealmObject not found
}
}
我如何对我的createSomeObject进行单元测试(例如createAccount(
@Test
public void create_someObj_test() {
String expectedReturnedName = "someName";
String actualReturnedName;
SomeRepositoryImpl manager; //Class with business logic (mvp pattern)
SomeRepositoryImpl.initialize();
manager = someRepositoryImpl.getInstance();
SomeRealmObject some = new SomeRealmObject();
some.setID(6);
some.setName(expectedReturnedName);
//mock adding user to realm, should actually add it to a list
mockRealm.beginTransaction();
mockRealm.copyToRealm(some);
mockRealm.commitTransaction();
actualReturnedName = mockRealm.where(SomeRealmObject.class).equalTo("id", some.getId()).findFirst().getName().toString();
//PASS if object exists and name matches
//FAIL if name does not match
//FAIL if nullPointerException because no match/object not found
assertEquals(expectedReturnedName, actualReturnedName );
}
这不是对你的问题的直接回答。 直接答案将涉及讨论findFirstAnswer
是什么以及它的name
属性包含什么。
不过,相反,我会问:"你想测试什么"? 这不是对 Realm DB 库的测试(这是一件好事(。 在我看来,这几乎就像是对 Mockito 的考验! 如果测试成功,您将知道 Mockito Mocks 可以返回具有特定名称的对象。
通常的做法是将数据层包装在一个非常薄的API中,类似于Spring等流行的数据访问对象。 如果你可以模拟数据API,你可以测试你的业务层。 如果你的数据 API 需要测试,你也可以测试诸如"这个 API 调用是否被转换为正确的查询?"或"如果结果为空,API 会崩溃吗?"之类的测试。
很抱歉这个倾斜的答案,但我认为如果你重新审视你试图测试的问题,整个问题可能会消失。