单元测试Realm用Mockito封装了LiveData

时间:2018-04-06 07:41:43

标签: android realm mockito android-livedata

我正在尝试Realm以及包括LiveData在内的Android架构组件。

我一直关注Google的应用程序架构指南:

https://developer.android.com/topic/libraries/architecture/guide.html

......用境界代替房间。

我从实现角度看一切都工作但是遇到了Mockito的问题我在尝试编写单元测试时还无法解决。

我已经在下面展示了我的测试,其中包含一些注释掉的内容以及到目前为止我所尝试的内容的解释以及结果:

@Test
public void loadCustomModelObjectsFromNetwork() throws IOException {

    // Prepare DAO
    MutableLiveData<List<CustomModelObject>> dbData = new MutableLiveData<>();

    // Compilation error
    //when(dao.getCustomModelObjects()).thenReturn(dbData);

    // Runtime exc.
    //doReturn(dbData).when(dao).getCustomModelObjects();

    // Runtime exc.
    //java.lang.ClassCastException: 
    //android.arch.lifecycle.MutableLiveData cannot be cast to LiveRealmResults
    doAnswer(new Answer() {
        @Override
        public Object answer(InvocationOnMock i) throws Throwable {
            // Made various attempts to convert to LiveRealmResults here 
            return dbData;
        }
    }).when(dao).getCustomModelObjects();

/*
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
MutableLiveData cannot be returned by getCustomModelObjectss()
getCustomModelObjects() should return LiveRealmResults
*/

    // Prepare REST service response
    List<CustomModelObject> customModelObjects = new ArrayList<>();
    CustomModelObject repo = new CustomModelObject();
    repo.setDescription("Desc1");
    customModelObjects.add(repo);

    CustomModelObjectsResponse response = new CustomModelObjectsResponse();
    response.setCustomModelObjects(customModelObjects);

    DocumentWrapper<CustomModelObjectsResponse> items = new DocumentWrapper<>();
    items.setBody(response);

    LiveData<ApiResponse<DocumentWrapper<CustomModelObjectsResponse>>> call = successCall(items);
    when(retrofitService.getCustomModelObjects()).thenReturn(call);
    when(service.getService()).thenReturn(retrofitService);

    // Item under test
    LiveData<Resource<List<CustomModelObject>>> data = repository.getCustomModelObjects();

    // Assertions
    verify(dao).getCustomModelObjects();

    verifyNoMoreInteractions(service);

    Observer observer = mock(Observer.class);
    data.observeForever(observer);
    verifyNoMoreInteractions(service);
    verify(observer).onChanged(Resource.loading(null));

    MutableLiveData<List<CustomModelObject>> updatedDbData = new MutableLiveData<>();
    //when(dao.getCustomModelObjects()).thenReturn(updatedDbData);
    doReturn(updatedDbData).when(dao).getCustomModelObjects();

    dbData.postValue(null);
    verify(retrofitService).getCustomModelObjects();
    verify(dao).save(customModelObjects);

    updatedDbData.postValue(customModelObjects);
    verify(observer).onChanged(Resource.success(repo));
}

即使在我的实现中它工作正常,LiveData<List<CustomModelObject>>也可以在单元测试中从LiveRealmResults<CustomModelObject>派生出来,我似乎无法将其与Mockito一起使用。

有关我的设置的更多实施细节可以在这里找到:

Using Realm and LiveData. Converting LiveData<RealmResults<CustomModelObject>> to LiveData<List<CustomModelObject>>

谢谢, 保罗。

更新

when(dao.getCustomModelObjects()).thenReturn(dbData);

has the following compilation error:

error: no suitable method found for 

thenReturn(MutableLiveData<List<CustomModelObject>>)
method OngoingStubbing.thenReturn(LiveRealmResults<CustomModelObject>) is not applicable
(argument mismatch; MutableLiveData<List<CustomModelObject>> cannot be converted to LiveRealmResults<CustomModelObject>)
method OngoingStubbing.thenReturn(LiveRealmResults<CustomModelObject>,LiveRealmResults<CustomModelObject>...) is not applicable
(argument mismatch; MutableLiveData<List<CustomModelObject>> cannot be converted to LiveRealmResults<CustomModelObject>)

1 个答案:

答案 0 :(得分:1)

public RealmLiveData<CustomModelObject> getCustomModelObjects() {
    return asLiveData(realm.where(CustomModelObject.class).findAllAsync());
}

应该是

public LiveData<List<<CustomModelObject>> getCustomModelObjects() {
    return asLiveData(realm.where(CustomModelObject.class).findAllAsync());
}

然后您的when(...)不应再出现编译错误。