单元测试在测试挂起功能时在 Android 中挂起



我在应用程序的存储库层中有一个挂起函数。我正在尝试对该函数进行单元测试,但每次执行时,它似乎都挂在await()调用上,然后永远停留在那里,永远不会完成。看起来后台发生了一些僵局,但并没有立即意识到发生了什么。

这里有人有什么解决方案吗?

这是我的回购函数:

suspend fun login(email: String, password: String): DataState<AuthViewState> {
try {
val authResult = firebaseAuth
.signInWithEmailAndPassword(email, password)
.await()
return DataState.data<AuthViewState>(
data = AuthViewState(
authResult.user?.uid
)
)
} catch (e: FirebaseAuthInvalidUserException) {
Log.e(TAG, "loginUserIfExisting: FirebaseAuthInvalidUserException: ", e)
return DataState.error<AuthViewState>(
"User not found. Please register."
)
} catch (e: FirebaseAuthInvalidCredentialsException) {
Log.e(TAG, "loginUserIfExisting: FirebaseAuthInvalidCredentialsException: ", e)
return DataState.error<AuthViewState>(
"Your password/email is incorrect. Please try again."
)
}
}

这是我的模拟测试:

@RunWith(JUnit4::class)
class AuthRepositoryTest {
private val email = "lee.a.wilson90@gmail.com"
private val password = "fakepassword"
private val CORRECT_USER_ID = "CORRECT_USER_ID"
private lateinit var SUT: AuthRepository
@Mock
private lateinit var firebaseAuth: FirebaseAuth
@Mock
private lateinit var authResultTask: Task<AuthResult>
@Mock
private lateinit var mockResult: AuthResult
@Mock
private lateinit var mockFirebaseUser: FirebaseUser
@Mock
private lateinit var mockUserPropertiesDao: UserPropertiesDao
@Mock
private lateinit var mockSharedPreferences: SharedPreferences
@Mock
private lateinit var mockSharedPreferencesEditor: SharedPreferences.Editor
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
`when`(firebaseAuth.signInWithEmailAndPassword(email, password))
.thenReturn(authResultTask)
`when`(mockResult.user)
.thenReturn(mockFirebaseUser)
`when`(mockFirebaseUser.uid)
.thenReturn("CORRECT_USER_ID")
`when`(mockUserPropertiesDao.searchByEmail(email))
.thenReturn(null)
`when`(mockSharedPreferences.getString(Constants.PREVIOUS_AUTH_USER, null))
.thenReturn(null)
SUT = AuthRepository(
firebaseAuth,
mockUserPropertiesDao,
mockSharedPreferences,
mockSharedPreferencesEditor
)
}
@Test
fun test_correctCredentialsEntered_correctOutputState() = runBlocking {
whenever(authResultTask.await()).thenReturn(mockResult)
val resultState = SUT.login(email, password)
val result = resultState.data!!.getContentIfNotHandled()!!.uid
assertEquals(CORRECT_USER_ID, result)
}
}

Mockito似乎还不支持挂起函数。

因此,与其嘲笑authResultTask: Task<AuthResult>(我认为这无论如何都是一个坏主意(,不如使用TaskCompletionSource<AuthResult>并设置它的结果。

编辑:

通过解释观察到的行为来完成这个答案。

单元测试挂起,因为当您模拟await()函数时,mockito 不会调用Continuation<T>.resume()

最新更新