class AuthRepositoryImpl @Inject constructor( private val auth: FirebaseAuth, private val dispatcher: CoroutineDispatcher = Dispatchers.IO ) : AuthRepository { override fun signIn(email: String, password: String): Flow = flow { emit(Resource.Loading) try { val result = auth.signInWithEmailAndPassword(email, password).await() val user = result.user if (user != null) { emit(Resource.success(user)) } else { emit(Resource.failure(Exception("User is not exist"))) } } catch (e: Exception) { emit(Resource.failure(e)) } }.flowOn(dispatcher) } @ExperimentalCoroutinesApi class AuthRepositoryImplTest { @MockK lateinit var firebaseAuth: FirebaseAuth private lateinit var authRepositoryImpl: AuthRepositoryImpl private val testDispatcher = StandardTestDispatcher() @Before fun setUp() { MockKAnnotations.init(this) authRepositoryImpl = AuthRepositoryImpl(firebaseAuth, testDispatcher) } @Test fun `signIn with valid credentials emits success`(): Unit = runTest(testDispatcher) { val email = "test@gmail.com" val password = "123456" val mockAuthResult: AuthResult = mockk(relaxed = true) val mockUser: FirebaseUser = mockk(relaxed = true) coEvery { firebaseAuth.signInWithEmailAndPassword(email, password).await() } returns mockAuthResult coEvery { mockAuthResult.user } returns mockUser val results = authRepositoryImpl.signIn(email, password).toList() // Kiểm tra kết quả có chứa Resource.Loading và Resource.Success hay không assertTrue(results.first() is Resource.Loading) assertTrue((results.last() as Resource.Success).value == mockUser) } }