单元测试中的RxJava,翻新,LiveData

时间:2020-08-28 09:00:45

标签: android mockito retrofit android-livedata

我正试图开始测试同时使用RxJava,Retrofit和LiveData的视图模型,但始终具有:NullPointerException。 因此,这是我的SplashViewModel,它可以同时从三个url下载数据,如果一切正常,该函数应将数据保存在Room Database中。在我的测试中,我只想检查一个网址,因此val error = MutableLiveData()获得真实值。 我做错了什么?我该怎么办?如何正确测试这种情况?

lass SplashViewModel @Inject constructor(private val photoRepository: PhotoRepository,
private val albumRepository: AlbumRepository,
private val userRepository: UserRepository,
@CoroutineScopeIO private val ioCoroutineScope: CoroutineScope) : ViewModel() {

val loading = MutableLiveData<Boolean>()
val error = MutableLiveData<Boolean>()
private lateinit var disposable: Disposable
private val requests = ArrayList<Observable<*>>()
var photos = ArrayList<RawPhoto>()
var albums = ArrayList<RawAlbum>()
var users = ArrayList<RawUser>()

init {
    fetchData()
}

 fun fetchData() {
    loading.postValue(true)

    requests.add(photoRepository.getPhotos()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread()))

    requests.add(albumRepository.getAlbums()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread()))

    requests.add(userRepository.getUsers()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread()))

     disposable = Observable.zip(requests){

         if (it[0] is List<*>) {                   //photos
             photos = it[0] as ArrayList<RawPhoto>
         }

         if (it[1] is List<*>) {                   //albums
             albums = it[1] as ArrayList<RawAlbum>
         }

         if (it[2] is List<*>) {                 //users
             users = it[2] as ArrayList<RawUser>
         }

         }
         .subscribe({
             ioCoroutineScope.launch {
                 photoRepository.insertPhotos(photos)
                 Timber.e("PHOTOS $photos")
             }
             ioCoroutineScope.launch {
                 albumRepository.insertAlbums(albums)
                 Timber.e("ALBUMS $albums")
             }
             ioCoroutineScope.launch {
                 userRepository.insertUsers(users)
                 Timber.e("USERS $users")
             }
             loading.postValue(false)
             Timber.e("Success")

         }) {
             error.postValue(true)
             Timber.e("Error")
         }
}

override fun onCleared() {
    super.onCleared()
    disposable.dispose()
    ioCoroutineScope.cancel()
}
}

测试类:

@RunWith(MockitoJUnitRunner::class)
class SplashViewModelTest {

@Mock
lateinit var photoRepository: PhotoRepository

@Mock
lateinit var albumRepository: AlbumRepository

@Mock
lateinit var userRepository: UserRepository

lateinit var splashViewModel: SplashViewModel
private val testDispatcher = TestCoroutineDispatcher()
private val testScope = TestCoroutineScope(testDispatcher)
lateinit var mockWebServer: MockWebServer
private lateinit var observablePhotos: Observable<List<RawPhoto>>


@Before
fun setUp() {
    MockitoAnnotations.initMocks(this)
    mockWebServer = MockWebServer()
    mockWebServer.start()
    splashViewModel = SplashViewModel(photoRepository, albumRepository, userRepository, testScope)
}

@After
fun tearDown() {
    mockWebServer.shutdown()
}

@Test
fun fetchJustOneUrl() {
    val rawPhoto1 = RawPhoto(1, 1, "Title1", "url1", "thumbUrl1")
    val rawPhoto2 = RawPhoto(2, 2, "Title2", "url2", "thumbUrl2")
    var rawPhotoList = ArrayList<RawPhoto>()
    rawPhotoList.add(rawPhoto1)
    rawPhotoList.add(rawPhoto2)
    observablePhotos = Observable.just(rawPhotoList)

    if (photoRepository != null) {
        Mockito.`when`(photoRepository.getPhotos()).thenReturn(observablePhotos)
    }

    splashViewModel.fetchData()
    Assert.assertEquals(2, splashViewModel.error.value == true)
}
}

0 个答案:

没有答案