Fahim
02/19/2024, 10:38 AMimport dev.icerock.moko.mvvm.viewmodel.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
class SignupOtpViewModel: ViewModel() {
private val _isNextButtonEnabledFlow = MutableStateFlow(false)
val isNextButtonEnabledFlow: StateFlow<Boolean>
get() = _isNextButtonEnabledFlow
val otpField = MutableStateFlow("")
init {
setupBinding()
}
// create setup binding for otpField. Set _isNextButtonEnabledFlow to true if otpField count is 6
fun setupBinding() {
otpField
.map { it.length == 6 }
.onEach { _isNextButtonEnabledFlow.value = it }
}
}
and this is my test class:
import kotlin.test.Test
import kotlin.test.assertEquals
class SignupOtpTests {
@Test
fun init_shouldDisableNextButton() {
val sut = makeSut()
assertEquals(sut.isNextButtonEnabledFlow.value, false)
}
@Test
fun fillCompleteOtp_shouldEnableNextButton() {
val sut = makeSut()
sut.otpField.value = "123456"
assertEquals(sut.isNextButtonEnabledFlow.value, true)
}
fun makeSut() : SignupOtpViewModel {
val sut = SignupOtpViewModel()
return sut
}
}
fillCompleteOtp_shouldEnableNextButton is failing. How can I fix it?dave08
02/20/2024, 1:53 PMlaunch { ... }
and in there call collect on that flow. The thing is how to replace that coroutine context in test code...Fahim
02/21/2024, 11:09 AMimport kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals
class SignupOtpTests {
@BeforeTest
fun setUp() {
Dispatchers.setMain(UnconfinedTestDispatcher())
}
@AfterTest
fun tearDown() {
Dispatchers.resetMain()
}
@Test
fun init_shouldDisableNextButton() {
val sut = makeSut()
assertEquals(sut.isNextButtonEnabled.value, false)
}
@Test
fun fillCompleteOtp_shouldEnableNextButton() = runTest {
val sut = makeSut()
sut.otpField.value = "123456"
assertEquals(sut.isNextButtonEnabled.value, true)
}
fun makeSut() : SignupOtpViewModel {
val sut = SignupOtpViewModel()
return sut
}
}
import dev.icerock.moko.mvvm.viewmodel.ViewModel
import dev.icerock.moko.mvvm.flow.cMutableStateFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import dev.icerock.moko.mvvm.flow.cStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
class SignupOtpViewModel: ViewModel() {
val _isNextButtonEnabled = MutableStateFlow(false)
val isNextButtonEnabled: StateFlow<Boolean>
get() = _isNextButtonEnabled.cStateFlow()
val otpField = MutableStateFlow("").cMutableStateFlow()
init {
setupBinding()
}
fun setupBinding() {
viewModelScope.launch {
otpField
.map { it.length == 6 }
.collect { _isNextButtonEnabled.value = it }
}
}
}