Issue#12 Finish ViewModel instruction set
This commit is contained in:
parent
89c741a6bb
commit
d339592390
7 changed files with 472 additions and 243 deletions
|
|
@ -14,7 +14,7 @@ import org.junit.jupiter.api.extension.BeforeEachCallback
|
|||
import org.junit.jupiter.api.extension.ExtensionContext
|
||||
|
||||
/**
|
||||
* Custom Junit5 Extension which replaces the [DatabaseInitialization]'s dispatcher and main dispatcher with a [TestCoroutineDispatcher]
|
||||
* Custom Junit5 Extension which replaces the [DatabaseInitialization]'s dispatcher and main dispatcher with a [TestDispatcher]
|
||||
*
|
||||
* One can access the test dispatcher via [testDispatcher] static getter.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -44,45 +44,59 @@ internal class AuthViewModelTest {
|
|||
@DisplayName("GIVEN initialized viewModel WHEN observed THEN loading false other fields are empty")
|
||||
@Test
|
||||
fun initialSetup() {
|
||||
val usernameTestObserver = sut.username.test()
|
||||
val passwordTestObserver = sut.password.test()
|
||||
val loadingTestObserver = sut.loading.test()
|
||||
val errorTestObserver = sut.error.test()
|
||||
val navigateToHomeTestObserver = sut.navigateToHome.test()
|
||||
|
||||
testScheduler.advanceUntilIdle()
|
||||
|
||||
sut.username.test().assertNoValue()
|
||||
sut.password.test().assertNoValue()
|
||||
sut.loading.test().assertValue(false)
|
||||
sut.error.test().assertNoValue()
|
||||
sut.navigateToHome.test().assertNoValue()
|
||||
usernameTestObserver.assertNoValue()
|
||||
passwordTestObserver.assertNoValue()
|
||||
loadingTestObserver.assertValue(false)
|
||||
errorTestObserver.assertNoValue()
|
||||
navigateToHomeTestObserver.assertNoValue()
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN password text WHEN onPasswordChanged is called THEN password livedata is updated")
|
||||
@Test
|
||||
fun whenPasswordChangedLiveDataIsUpdated() {
|
||||
val usernameTestObserver = sut.username.test()
|
||||
val passwordTestObserver = sut.password.test()
|
||||
val loadingTestObserver = sut.loading.test()
|
||||
val errorTestObserver = sut.error.test()
|
||||
val navigateToHomeTestObserver = sut.navigateToHome.test()
|
||||
|
||||
sut.onPasswordChanged("a")
|
||||
sut.onPasswordChanged("al")
|
||||
testScheduler.advanceUntilIdle()
|
||||
|
||||
usernameTestObserver.assertNoValue()
|
||||
passwordTestObserver.assertValueHistory("a", "al")
|
||||
sut.username.test().assertNoValue()
|
||||
sut.loading.test().assertValue(false)
|
||||
sut.error.test().assertNoValue()
|
||||
sut.navigateToHome.test().assertNoValue()
|
||||
loadingTestObserver.assertValue(false)
|
||||
errorTestObserver.assertNoValue()
|
||||
navigateToHomeTestObserver.assertNoValue()
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN username text WHEN onUsernameChanged is called THEN username livedata is updated")
|
||||
@Test
|
||||
fun whenUsernameChangedLiveDataIsUpdated() {
|
||||
val usernameTestObserver = sut.username.test()
|
||||
val passwordTestObserver = sut.password.test()
|
||||
val loadingTestObserver = sut.loading.test()
|
||||
val errorTestObserver = sut.error.test()
|
||||
val navigateToHomeTestObserver = sut.navigateToHome.test()
|
||||
|
||||
sut.onUsernameChanged("a")
|
||||
sut.onUsernameChanged("al")
|
||||
sut.onUsernameChanged("bla")
|
||||
sut.onUsernameChanged("blabla")
|
||||
testScheduler.advanceUntilIdle()
|
||||
|
||||
usernameTestObserver.assertValueHistory("a", "al")
|
||||
sut.password.test().assertNoValue()
|
||||
sut.loading.test().assertValue(false)
|
||||
sut.error.test().assertNoValue()
|
||||
sut.navigateToHome.test().assertNoValue()
|
||||
usernameTestObserver.assertValueHistory("bla", "blabla")
|
||||
passwordTestObserver.assertNoValue()
|
||||
loadingTestObserver.assertValue(false)
|
||||
errorTestObserver.assertNoValue()
|
||||
navigateToHomeTestObserver.assertNoValue()
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN no password or username WHEN login is Called THEN empty credentials are used in usecase")
|
||||
|
|
@ -122,6 +136,7 @@ internal class AuthViewModelTest {
|
|||
}
|
||||
sut.onPasswordChanged("pass")
|
||||
sut.onUsernameChanged("usr")
|
||||
testScheduler.advanceUntilIdle()
|
||||
|
||||
sut.onLogin()
|
||||
testScheduler.advanceUntilIdle()
|
||||
|
|
@ -134,20 +149,20 @@ internal class AuthViewModelTest {
|
|||
|
||||
@DisplayName("GIVEN AnswerError WHEN login called THEN error is shown")
|
||||
@Test
|
||||
fun loginErrorResultsInErrorState() {
|
||||
fun loginUnexpectedErrorResultsInErrorState() {
|
||||
runBlocking {
|
||||
whenever(mockLoginUseCase.invoke(anyOrNull())).doReturn(Answer.Error(Throwable()))
|
||||
}
|
||||
val loadingObserver = sut.loading.test()
|
||||
val errorObserver = sut.error.test()
|
||||
val navigateToHomeObserver = sut.navigateToHome.test()
|
||||
val loadingTestObserver = sut.loading.test()
|
||||
val errorTestObserver = sut.error.test()
|
||||
val navigateToHomeTestObserver = sut.navigateToHome.test()
|
||||
|
||||
sut.onLogin()
|
||||
testScheduler.advanceUntilIdle()
|
||||
|
||||
loadingObserver.assertValueHistory(false, true, false)
|
||||
errorObserver.assertValueHistory(Event(AuthViewModel.ErrorType.GENERAL_NETWORK_ERROR))
|
||||
navigateToHomeObserver.assertNoValue()
|
||||
loadingTestObserver.assertValueHistory(false, true, false)
|
||||
errorTestObserver.assertValueHistory(Event(AuthViewModel.ErrorType.GENERAL_NETWORK_ERROR))
|
||||
navigateToHomeTestObserver.assertNoValue()
|
||||
}
|
||||
|
||||
@MethodSource("loginErrorStatusesArguments")
|
||||
|
|
@ -159,16 +174,16 @@ internal class AuthViewModelTest {
|
|||
runBlocking {
|
||||
whenever(mockLoginUseCase.invoke(anyOrNull())).doReturn(Answer.Success(loginStatus))
|
||||
}
|
||||
val loadingObserver = sut.loading.test()
|
||||
val errorObserver = sut.error.test()
|
||||
val navigateToHomeObserver = sut.navigateToHome.test()
|
||||
val loadingTestObserver = sut.loading.test()
|
||||
val errorTestObserver = sut.error.test()
|
||||
val navigateToHomeTestObserver = sut.navigateToHome.test()
|
||||
|
||||
sut.onLogin()
|
||||
testScheduler.advanceUntilIdle()
|
||||
|
||||
loadingObserver.assertValueHistory(false, true, false)
|
||||
errorObserver.assertValueHistory(Event(errorType))
|
||||
navigateToHomeObserver.assertNoValue()
|
||||
loadingTestObserver.assertValueHistory(false, true, false)
|
||||
errorTestObserver.assertValueHistory(Event(errorType))
|
||||
navigateToHomeTestObserver.assertNoValue()
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN answer success and login status success WHEN login called THEN navigation event is sent")
|
||||
|
|
@ -177,16 +192,16 @@ internal class AuthViewModelTest {
|
|||
runBlocking {
|
||||
whenever(mockLoginUseCase.invoke(anyOrNull())).doReturn(Answer.Success(LoginStatus.SUCCESS))
|
||||
}
|
||||
val loadingObserver = sut.loading.test()
|
||||
val errorObserver = sut.error.test()
|
||||
val navigateToHomeObserver = sut.navigateToHome.test()
|
||||
val loadingTestObserver = sut.loading.test()
|
||||
val errorTestObserver = sut.error.test()
|
||||
val navigateToHomeTestObserver = sut.navigateToHome.test()
|
||||
|
||||
sut.onLogin()
|
||||
testScheduler.advanceUntilIdle()
|
||||
|
||||
loadingObserver.assertValueHistory(false, true, false)
|
||||
errorObserver.assertNoValue()
|
||||
navigateToHomeObserver.assertValueHistory(Event(Unit))
|
||||
loadingTestObserver.assertValueHistory(false, true, false)
|
||||
errorTestObserver.assertNoValue()
|
||||
navigateToHomeTestObserver.assertValueHistory(Event(Unit))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -5,20 +5,18 @@ import org.fnives.test.showcase.core.login.LoginUseCase
|
|||
import org.fnives.test.showcase.testutils.InstantExecutorExtension
|
||||
import org.fnives.test.showcase.testutils.TestMainDispatcher
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.mockito.kotlin.mock
|
||||
|
||||
@Disabled("CodeKata")
|
||||
@ExtendWith(InstantExecutorExtension::class, TestMainDispatcher::class)
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class CodeKataAuthViewModel {
|
||||
|
||||
private lateinit var sut: AuthViewModel
|
||||
private lateinit var mockLoginUseCase: LoginUseCase
|
||||
private val testDispatcher get() = TestMainDispatcher.testDispatcher
|
||||
private val testScheduler get() = TestMainDispatcher.testDispatcher.scheduler
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
|
|
@ -45,4 +43,29 @@ class CodeKataAuthViewModel {
|
|||
@Test
|
||||
fun noPasswordUsesEmptyStringInLoginUseCase() {
|
||||
}
|
||||
|
||||
@DisplayName("WHEN login is called twice before finishing THEN use case is only called once")
|
||||
@Test
|
||||
fun onlyOneLoginIsSentOutWhenClickingRepeatedly() {
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN password and username WHEN login is called THEN proper credentials are used in usecase")
|
||||
@Test
|
||||
fun argumentsArePassedProperlyToLoginUseCase() {
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN AnswerError WHEN login called THEN error is shown")
|
||||
@Test
|
||||
fun loginUnexpectedErrorResultsInErrorState() {
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN answer success loginStatus INVALID_CREDENTIALS WHEN login called THEN error INVALID_CREDENTIALS is shown")
|
||||
@Test
|
||||
fun invalidStatusResultsInErrorState() {
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN answer success and login status success WHEN login called THEN navigation event is sent")
|
||||
@Test
|
||||
fun successLoginResultsInNavigation() {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
package org.fnives.test.showcase.ui.splash
|
||||
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
@Disabled("CodeKata")
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
internal class CodeKataSplashViewModelTest {
|
||||
|
||||
@BeforeEach
|
||||
|
|
@ -19,7 +21,7 @@ internal class CodeKataSplashViewModelTest {
|
|||
|
||||
@DisplayName("GIVEN logged in user WHEN splash started THEN after half a second navigated to home")
|
||||
@Test
|
||||
fun loggedInUserGoestoHome() {
|
||||
fun loggedInUserGoesToHome() {
|
||||
}
|
||||
|
||||
@DisplayName("GIVEN not logged in user WHEN splash started THEN before half a second no event is sent")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue