UseCase Tests
This page covers testing patterns for Use Cases. Use cases are tested with Mockito-Kotlin (not MockK) β see the Mocking Strategy section for why two libraries are used.
UseCase Testing Patternsβ
Use cases contain validation logic and delegate to repositories. They are tested to validate input normalization, validation errors, and correct repository delegation.
class AuthUseCasesTest {
private lateinit var authRepository: AuthRepository
@Before
fun setup() {
Dispatchers.setMain(testDispatcher)
authRepository = mock()
}
@Test
fun `LoginUseCase - normalizes email to lowercase and trims`() = runTest {
val useCase = LoginUseCase(authRepository)
val loginResult = createTestLoginResult()
whenever(authRepository.login("user@example.com", "password123")).thenReturn(loginResult)
useCase(" USER@EXAMPLE.COM ", "password123")
verify(authRepository).login("user@example.com", "password123")
}
@Test(expected = InvalidEmailException::class)
fun `LoginUseCase - throws InvalidEmailException when email is empty`() = runTest {
val useCase = LoginUseCase(authRepository)
useCase("", "password123")
}
@Test
fun `LoginUseCase - returns Requires2FA when 2FA is required`() = runTest {
val useCase = LoginUseCase(authRepository)
whenever(authRepository.login("test@example.com", "password123"))
.thenAnswer { throw TwoFactorRequiredException("temp_token_123", "totp") }
val response = useCase("test@example.com", "password123")
assertTrue(response is LoginResponse.Requires2FA)
assertEquals("temp_token_123", (response as LoginResponse.Requires2FA).tempToken)
}
}
Use cases instantiate the subject under test directly (LoginUseCase(authRepository)) rather than using DI, since use cases are simple classes with a single repository dependency.
For use cases that return Flow emissions, Turbine is used for assertions β see Flow Testing with Turbine for the full pattern and examples including RealTimeUseCasesTest and UserProfileInteractor.