Нужно ли имитировать интерфейсы, которые не вызывают, например, поле имени пользователя и пароля пустое? Сначала я пытаюсь написать тест, но не понимаю, нужно ли использовать макеты.
Мой тест входа в систему
private val authRepository: AuthRepository = mockk()
private val userManager: AccountManager = mockk()
private lateinit var authUseCase: AuthUseCase
@BeforeEach
fun setUp() {
clearMocks(authRepository)
clearMocks(userManager)
authUseCase = AuthUseCase(authRepository, userManager)
}
/**
* Scenario: Login check with empty fields:
* * Given I am on the login page
* * When I enter empty username
* And I enter empty password
* And I click on the "Login" button
* * Then I get empty fields error.
*/
@Test
fun `Empty fields result empty fields error`() {
// Given
// When
val expected = authUseCase.login("", "", false)
// Then
verify(exactly = 0) { authRepository.login(or(any(), ""), or(any(), ""), any()) }
expected assertEquals EMPTY_FIELD_ERROR
}
Нужно ли мне макетировать интерфейс для данной части теста или даже AccountManager? хотя они не вызываются, так как имя пользователя и / или поля пусты?
Это последняя версия метода входа в систему, которую я намереваюсь написать после тестов
class AuthUseCase(
private val authRepository: AuthRepository,
private val accountManager: AccountManager
) {
private var loginAttempt = 1
/*
STEP 1: Throw exception for test to compile and fail
*/
// fun login(
// userName: String,
// password: String,
// rememberMe: Boolean = false
// ): AuthenticationState {
// throw NullPointerException()
// }
/*
STEP3: Check if username or password is empty
*/
// fun login(
// userName: String,
// password: String,
// rememberMe: Boolean = false
// ): AuthenticationState {
//
//
// if (userName.isNullOrBlank() || password.isNullOrBlank()) {
// return EMPTY_FIELD_ERROR
// }else {
// throw NullPointerException()
// }
//
// }
/**
* This is the final and complete version of the method.
*/
fun login(
userName: String,
password: String,
rememberMe: Boolean
): AuthenticationState {
return if (loginAttempt >= MAX_LOGIN_ATTEMPT) {
MAX_NUMBER_OF_ATTEMPTS_ERROR
} else if (userName.isNullOrBlank() || password.isNullOrBlank()) {
EMPTY_FIELD_ERROR
} else if (!checkUserNameIsValid(userName) || !checkIfPasswordIsValid(password)) {
INVALID_FIELD_ERROR
} else {
// Concurrent Authentication via mock that returns AUTHENTICATED, or FAILED_AUTHENTICATION
val authenticationPass =
getAccountResponse(userName, password, rememberMe)
return if (authenticationPass) {
loginAttempt = 0
AUTHENTICATED
} else {
loginAttempt++
FAILED_AUTHENTICATION
}
}
}
private fun getAccountResponse(
userName: String,
password: String,
rememberMe: Boolean
): Boolean {
val authResponse =
authRepository.login(userName, password, rememberMe)
val authenticationPass = authResponse?.authenticated ?: false
authResponse?.token?.let {
accountManager.saveToken(it)
}
return authenticationPass
}
private fun checkUserNameIsValid(field: String): Boolean {
return field.length >15 && field.endsWith("@example.com")
}
private fun checkIfPasswordIsValid(field: String): Boolean {
return field.length in 6..10
}
}
Должен ли я издеваться, когда все другие состояния и пройдено, я получаю ложный ответ из репозитория, и происходит взаимодействие с менеджером аккаунта?
Что следует дать в разделе теста?
Редактировать:
Я обновил данный раздел этого теста до
@Test
fun `Empty fields result empty fields error`() {
// Given
every { authRepository.login(or(any(), ""), or(any(), "")) } returns null
// When
val expected = authUseCase.login("", "", false)
// Then
verify(exactly = 0) { authRepository.login(or(any(), ""), or(any(), "")) }
expected assertThatEquals EMPTY_FIELD_ERROR
}
Что-то не так с таким поведенческим тестированием?