'Testing viewModel with liveData and rxJava actual array was <null>

I want to ensure that after viewModel method is called liveData has a value. Had a problem with liveData.getValue() which is always null while testing viewModel with rxJava Single.

Error messages(there is an assertion on line 69):

actual array was <null>
org.opentest4j.AssertionFailedError: actual array was <null>
    at app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:39)
    at app//org.junit.jupiter.api.AssertArrayEquals.failActualArrayIsNull(AssertArrayEquals.java:413)
    at app//org.junit.jupiter.api.AssertArrayEquals.assertArraysNotNull(AssertArrayEquals.java:404)
    at app//org.junit.jupiter.api.AssertArrayEquals.assertArrayEquals(AssertArrayEquals.java:337)
    at app//org.junit.jupiter.api.AssertArrayEquals.assertArrayEquals(AssertArrayEquals.java:162)
    at app//org.junit.jupiter.api.AssertArrayEquals.assertArrayEquals(AssertArrayEquals.java:158)
    at app//org.junit.jupiter.api.Assertions.assertArrayEquals(Assertions.java:1452)
    at app//com.online.shop.ui.list.ProductListViewModelTest.testGetCellphones_whenReturnsData(ProductListViewModelTest.java:69)

I've tried LiveDataTestUtil, however the result is the same. Also during the debug find out that pending data of liveData is initialized

Test class implementation:

@ExtendWith(MockitoExtension.class)
public class ProductListViewModelTest {
    @Rule
    public InstantTaskExecutorRule instantTaskExecutorRule = new InstantTaskExecutorRule();

    @Rule
    public RxImmediateSchedulerRule testSchedulerRule = new RxImmediateSchedulerRule();

    @Rule
    public MockitoRule rule = MockitoJUnit.rule();

    @Mock
    GetCellphonesInteractor getCellphonesInteractor;
    @Mock
    GetCellphonesByNameInteractor getCellphonesByNameInteractor;
    @Mock
    GetFilteredCellphonesInteractor getFilteredCellphonesInteractor;

    TrampolineSchedulerProvider trampolineSchedulerProvider = new TrampolineSchedulerProvider();

    @Test
    public void testGetCellphones_whenReturnsData() {
        Cellphone[] dummyCellphones = DummyCellphoneFactory.generateCellphones();

        ProductListViewModel productListViewModel = new ProductListViewModel(
            getCellphonesInteractor,
            getCellphonesByNameInteractor,
            getFilteredCellphonesInteractor,
            trampolineSchedulerProvider
        );

        Mockito.when(getCellphonesInteractor.getCellPhones()).thenReturn(Single.just(dummyCellphones));

        productListViewModel.getCellphones();

        try {
            LiveDataTestUtil.getValue(productListViewModel.cellphonesLiveData);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Assertions.assertEquals(true, productListViewModel.isRefreshing.getValue());
        Assertions.assertArrayEquals(dummyCellphones, productListViewModel.cellphonesLiveData.getValue());
        Assertions.assertEquals(false, productListViewModel.isRefreshing.getValue());
//        productListViewModel.cellphonesLiveData.observeForever(value ->
//            Assertions.assertArrayEquals(dummyCellphones, value)
//        );
    }
}

ViewModel method

 void getCellphones() {
        getCellphonesInteractor
            .getCellPhones()
            .subscribeOn(schedulerProvider.io())
            .observeOn(schedulerProvider.io())
            .subscribe(new SingleObserver<Cellphone[]>() {
                @Override
                public void onSubscribe(@NonNull Disposable d) {
                    disposables.add(d);
                    _isRefreshing.postValue(true);
                }

                @Override
                public void onSuccess(@NonNull Cellphone[] cellphones) {
                    _cellphonesLiveData.postValue(cellphones);
                    _isRefreshing.postValue(false);
                }

                @Override
                public void onError(@NonNull Throwable e) {
                    e.printStackTrace();
                    _cellPhoneEvent.postValue(CellPhonesEvent.ERROR);
                    _isRefreshing.postValue(false);
                }
            });
    }


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source