我正在使用JUnit4和Mockito测试我的身份验证类。我写了以下简单的测试类:
@ExperimentalCoroutinesApi
class FirebaseAuthenticationDataSourceTest {
@get:Rule
val mockitoRule: MockitoRule = MockitoJUnit.rule()
@get:Rule
val instantTaskExecutorRule = InstantTaskExecutorRule()
@Mock
var mockAuth: FirebaseAuth = mock()
@Mock
lateinit var mockSharedPref: SharedPreferences
@InjectMocks
lateinit var dataSource: FirebaseAuthenticationDataSource
@Before
fun setup() {
// Inizializza i mock e il data source prima di ogni test
MockitoAnnotations.openMocks(this)
}
@Test
fun `signIn success - should emit Success result with user data`() = runTest {
// Mock il comportamento di FirebaseAuth.signInWithEmailAndPassword
val mockAuthResult = mock<AuthResult>()
val mockFirebaseUser = mock<FirebaseUser> {
on { email } doReturn "test@example.com"
on { uid } doReturn "12345"
on { displayName } doReturn "Test User"
}
// Utilizza when invece di whenever per mockAuth
`when`(mockAuth.signInWithEmailAndPassword(any(), any())).thenReturn(mockTask(mockAuthResult)) //line 69
`when`(mockAuthResult.user).thenReturn(mockFirebaseUser)
// Esegui il metodo signIn del data source
val signInFlow = dataSource.signIn("test@example.com", "password")
// Ottieni i risultati dalla flow e verificali
val results = signInFlow.toList()
assertEquals(2, results.size)
assertEquals(Result.Loading, results[0])
assertEquals(Result.Success(User("test@example.com", "12345", "Test User")), results[1])
}
private fun <T> mockTask(result: T): Task<T> {
val mockTask = mock<Task<T>>()
whenever(mockTask.isSuccessful).thenReturn(true)
whenever(mockTask.result).thenReturn(result)
return mockTask
}
}
它测试以下方法:
class FirebaseAuthenticationDataSource
@Inject
constructor(
private val auth: FirebaseAuth,
private val sharedPref: SharedPreferences
) : AuthDataSource {
override fun signIn(email: String, password: String): Flow<Result<User>> = flow {
emit(Result.Loading)
try {
val result = auth.signInWithEmailAndPassword(email, password).await()
emit(
Result.Success(
User(
result.user!!.email ?: "",
result.user!!.uid,
result.user!!.displayName ?: ""
)
)
)
} catch (e: Exception) {
emit(Result.Error(e))
}
}
}
在这种情况下,前面的方法必须允许用户使用Firebase作为提供程序登录。
但是当我启动测试时,我得到了这个错误:
Unfinished stubbing detected here:
-> at com.indisparte.loginfeature.data.datasource.FirebaseAuthenticationDataSourceTest$signIn success - should emit Success result with user data$1.invokeSuspend(FirebaseAuthenticationDataSourceTest.kt:69)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, which is not supported
3. you are stubbing the behaviour of another mock inside before 'thenReturn' instruction is completed
我不明白错误在哪里,在互联网上搜索,似乎我正在嫁接模拟,但我不明白在哪里。
1条答案
按热度按时间mwkjh3gx1#
当你测试类的时候,你需要对他使用@InejctMocks。@InjectMocks创建类的示例,并将使用@Mock(或@Spy)注解创建的模拟注入到该示例中。所以换掉这个
用这个: