AssertionError в модульном тестировании viewModel - PullRequest
0 голосов
/ 07 октября 2019

У меня есть следующий проект в Bitbucket: https://bitbucket.org/ali-rezaei/storytel/src/master/

У меня есть следующий unitTest:

@RunWith(MockitoJUnitRunner::class)
class MainViewModelTest {

    @get:Rule
    var rule: TestRule = InstantTaskExecutorRule()

    @Mock
    private lateinit var api: StorytelService

    private lateinit var viewModel: MainViewModel

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
    }

    @Test
    fun loadPosts() {
        val networkPhoto = NetworkPhoto(1, 1, "title", "url", "thumbnailUrl")
        `when`(api.getPhotos()).thenReturn(Observable.just(listOf(networkPhoto)))

        val networkPost = NetworkPost(1, 1, "title", "body")
        `when`(api.getPosts()).thenReturn(Observable.just(listOf(networkPost)))

        // Make the sure that all schedulers are immediate.
        val schedulerProvider = ImmediateSchedulerProvider()

        viewModel = MainViewModel(schedulerProvider, api)

        val observer = LoggingObserver<List<Post>>()
        viewModel.posts.observeForever(observer)

        with(observer) {
            assertThat(this, `is`(notNullValue()))
            assertThat(this.value?.size, `is`(1))
        }
    }

    /**
     * simple observer that logs the latest value it receives
     */
    private class LoggingObserver<T> : Observer<T> {
        var value: T? = null
        override fun onChanged(t: T?) {
            this.value = t
        }
    }
}

Это результат:

java.lang.AssertionError: 
Expected: is <1>
     but: was null
Expected :is <1>
Actual   :null

И вотКласс MainViewModel:

class MainViewModel(
    private val schedulerProvider: BaseSchedulerProvider,
    private val api : StorytelService
) : BaseViewModel() {

    private val _posts = MutableLiveData<List<Post>>()
    val posts: LiveData<List<Post>>
        get() = _posts

    private val _status = MutableLiveData<Status>()
    val status: LiveData<Status>
        get() = _status

    init {
        showPhotos()
    }

    fun showPhotos() {
        EspressoIdlingResource.increment() // App is busy until further notice
        _status.postValue(Status.LOADING)
        compositeDisposable.add(api.getPhotos()
            .subscribeOn(schedulerProvider.io())
            .observeOn(schedulerProvider.ui())
            .doFinally {
                if (!EspressoIdlingResource.countingIdlingResource.isIdleNow) {
                    EspressoIdlingResource.decrement() // Set app as idle.
                }
            }
            .subscribe({
                _status.postValue(Status.SUCCESS)
                showPosts(it)
            }) {
                _status.postValue(Status.ERROR)
                Timber.e(it)
            })
    }

    private fun showPosts(networkPhotos: List<NetworkPhoto>) {
        EspressoIdlingResource.increment() // App is busy until further notice
        _status.postValue(Status.LOADING)
        compositeDisposable.add(api.getPosts()
            .subscribeOn(schedulerProvider.io())
            .observeOn(schedulerProvider.ui())
            .doFinally {
                if (!EspressoIdlingResource.countingIdlingResource.isIdleNow) {
                    EspressoIdlingResource.decrement() // Set app as idle.
                }
            }
            .subscribe({ networkPosts ->
                _status.postValue(Status.SUCCESS)
                _posts.postValue(
                    PostAndImages(networkPosts, networkPhotos).asDomaineModel()
                )
            }) {
                _status.postValue(Status.ERROR)
                Timber.e(it)
            })
    }
}

Как решить эту проблему?

1 Ответ

0 голосов
/ 07 октября 2019

Проблема вызвана этой строкой:

val networkPhoto = networkPhotos[Random().nextInt(networkPhotos.size - 1)]

, поскольку в вашем списке networkPhotos есть только одна фотография, код вызывает Random().nextInt(0).

Глядя на документацию nextInt(int bound) , вы можете видеть, что ноль не является допустимым аргументом, и по этой причине выдается IllegalArgumentException.

Вы должны провести санитарную обработкуаргумент перед вызовом nextInt.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...