I am begginer in testing android apps. I have problem while testing my viewmodel. I want to test view model function which gets data from repository and make some logic with it.
class CurrencyViewModel(
private val repository: Repository
) : ViewModel() {
private var day: LocalDate = LocalDate.now()
private val listWithFormattedCurrencies = mutableListOf<CurrencyInfo>()
var currencyList = MutableLiveData<MutableList<CurrencyInfo>>()
fun getRecordsFromFixer() {
CoroutineScope(Dispatchers.IO).launch {
var listWithCurrencies: MutableList<CurrencyInfo>
val formatter = DateTimeFormatter.ISO_LOCAL_DATE
val formatted = day.format(formatter)
listWithCurrencies = repository.getRecordsFromApi(formatted)
for (i in listWithCurrencies) {
val formattedRate = formattingRates(i.currency, i.rate)
listWithFormattedCurrencies.add(CurrencyInfo(i.date, i.currency, formattedRate))
}
currencyList.postValue(listWithFormattedCurrencies)
day = day.minusDays(1)
}
}
private fun formattingRates(name : String, rate : String): String {
return if(name =="BTC" && name.isNotEmpty() && rate.isNotEmpty()){
String.format("%.8f", rate.toDouble())
}else if (name.isNotEmpty() && rate.isNotEmpty()){
String.format("%.4f", rate.toDouble())
}else{
rate
}
}
}
class CurrencyViewModelTest {
@ExperimentalCoroutinesApi
private val testDispatcher = StandardTestDispatcher()
@get:Rule
val rule = InstantTaskExecutorRule()
private lateinit var viewModel: CurrencyViewModel
@Before
fun setUp() {
Dispatchers.setMain(testDispatcher)
}
@After
fun tearDown(){
Dispatchers.resetMain()
}
@Test
fun `formatting empty name returns empty rate` () = runBlocking{
val currencyRepository = mock(currencyRepository::class.java)
val viewModel = CurrencyViewModel(currencyRepository)
val date = "2022-02-02"
val listOfCurrencies = mutableListOf(CurrencyInfo(date,"", "0.222"))
Mockito.`when` (currencyRepository.getRecordsFromApi(date)).thenReturn(listOfCurrencies)
viewModel.getRecordsFromFixer()
assertThat(viewModel.currencyList.getOrAwaitValue().contains(CurrencyInfo(date,"",""))).isTrue()
}
}
Error
Exception in thread "DefaultDispatcher-worker-1 @coroutine#2" java.lang.NullPointerException
.
.
.
LiveData value was never set.
java.util.concurrent.TimeoutException: LiveData value was never set.
The problem is that currencyRepository.getRecordsFromApi(date)) returns null object.
I tried to check if currencyRepository.getRecordsFromApi(date)) returns proper data after initializing it apart from ViewModel function and it works fine.
Why currencyRepository.getRecordsFromApi(date)) returns null when it is invoked in ViewModel function?