单元测试 Realm 用 Mockito 包装了 LiveData

Unit testing Realm wrapped LiveData with Mockito

我正在试用 Realm 以及 Android 架构组件,包括 LiveData。

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

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

...将 Room 替换为 Realm。

我从实现的角度来看一切正常,但是 运行 在尝试编写单元测试时我无法解决 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 一起工作。

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

谢谢, 保罗.

更新

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>)
public RealmLiveData<CustomModelObject> getCustomModelObjects() {
    return asLiveData(realm.where(CustomModelObject.class).findAllAsync());
}

应该是

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

那么你的when(...)应该不会再出现编译错误了。