使用 Mockito 测试 firebase 登录时出错
Error testing firebase login with Mockito
我有使用 firebase 登录用户的登录表单,我正在尝试通过编写一些代码来测试登录功能,我使用 Mockito 来模拟 firebase class 但对于某些人来说它一直失败并且我觉得有问题,如果有人可以帮助解决这个问题,谢谢
- 这是我的代码
@RunWith(AndroidJUnit4ClassRunner::class)
class LoginActivityTest {
@get:Rule
var scenario = ActivityScenarioRule(LoginActivity::class.java)
private lateinit var emailEditText : TextInputLayout
private lateinit var passwordEditText : TextInputLayout
private lateinit var firebaseUser: FirebaseUser
@Test
fun testCaseRealUserLogin(){
scenario.scenario.onActivity { it ->
emailEditText = it.findViewById(R.id.loginEmail)
passwordEditText = it.findViewById(R.id.loginPassword)
}
Looper.prepare()
emailEditText.editText!!.setText("xxxxxx@gmail.com")
passwordEditText.editText!!.setText("xxxxxx")
onView(withId(R.id.loginBtn)).perform(click())
//Mocking firebase
val firebaseMock = mock(FirebaseAuth::class.java)
`when`(firebaseMock.signInWithEmailAndPassword("xxxxxxx","xxxxxxx"))
.thenReturn(notNull())
firebaseUser = firebaseMock.currentUser!!
assertNotNull(firebaseUser)
}
}
简单的回答。 activity 没有使用模拟的 class!!。它使用真实的 FirebaseAuth
.
因此您需要将模拟的 class 提供给 activity。
简单的方法是 ServiceLocator 模式
先创建一个ServiceLocator.ktclass
object ServiceLocator {
var auth = Firebase.auth
}
并在生产代码中使用它而不是实例化 auth
对象
// in activity to sign in
ServiceLocator.auth.createUserWithEmailAndPassword(email, password)
其次你需要在测试时用模拟的class替换真实的
fun testCaseRealUserLogin(){
scenario.scenario.onActivity { it ->
emailEditText = it.findViewById(R.id.loginEmail)
passwordEditText = it.findViewById(R.id.loginPassword)
}
Looper.prepare()
emailEditText.editText!!.setText("xxxxxx@gmail.com")
passwordEditText.editText!!.setText("xxxxxx")
//Mocking firebase
val firebaseMock = mock(FirebaseAuth::class.java)
// make activity using the mocked class here ---------------
ServiceLocator.auth = firebaseMock
onView(withId(R.id.loginBtn)).perform(click())
// this assertion will pass
`when`(firebaseMock.signInWithEmailAndPassword("xxxxxxx","xxxxxxx"))
.thenReturn(notNull())
firebaseUser = firebaseMock.currentUser!!
// NOTE: this assertion will fail as the mocked class will always return null and not the actual value
assertNotNull(firebaseUser)
}
我有使用 firebase 登录用户的登录表单,我正在尝试通过编写一些代码来测试登录功能,我使用 Mockito 来模拟 firebase class 但对于某些人来说它一直失败并且我觉得有问题,如果有人可以帮助解决这个问题,谢谢
- 这是我的代码
@RunWith(AndroidJUnit4ClassRunner::class)
class LoginActivityTest {
@get:Rule
var scenario = ActivityScenarioRule(LoginActivity::class.java)
private lateinit var emailEditText : TextInputLayout
private lateinit var passwordEditText : TextInputLayout
private lateinit var firebaseUser: FirebaseUser
@Test
fun testCaseRealUserLogin(){
scenario.scenario.onActivity { it ->
emailEditText = it.findViewById(R.id.loginEmail)
passwordEditText = it.findViewById(R.id.loginPassword)
}
Looper.prepare()
emailEditText.editText!!.setText("xxxxxx@gmail.com")
passwordEditText.editText!!.setText("xxxxxx")
onView(withId(R.id.loginBtn)).perform(click())
//Mocking firebase
val firebaseMock = mock(FirebaseAuth::class.java)
`when`(firebaseMock.signInWithEmailAndPassword("xxxxxxx","xxxxxxx"))
.thenReturn(notNull())
firebaseUser = firebaseMock.currentUser!!
assertNotNull(firebaseUser)
}
}
简单的回答。 activity 没有使用模拟的 class!!。它使用真实的 FirebaseAuth
.
因此您需要将模拟的 class 提供给 activity。
简单的方法是 ServiceLocator 模式
先创建一个ServiceLocator.ktclass
object ServiceLocator {
var auth = Firebase.auth
}
并在生产代码中使用它而不是实例化 auth
对象
// in activity to sign in
ServiceLocator.auth.createUserWithEmailAndPassword(email, password)
其次你需要在测试时用模拟的class替换真实的
fun testCaseRealUserLogin(){
scenario.scenario.onActivity { it ->
emailEditText = it.findViewById(R.id.loginEmail)
passwordEditText = it.findViewById(R.id.loginPassword)
}
Looper.prepare()
emailEditText.editText!!.setText("xxxxxx@gmail.com")
passwordEditText.editText!!.setText("xxxxxx")
//Mocking firebase
val firebaseMock = mock(FirebaseAuth::class.java)
// make activity using the mocked class here ---------------
ServiceLocator.auth = firebaseMock
onView(withId(R.id.loginBtn)).perform(click())
// this assertion will pass
`when`(firebaseMock.signInWithEmailAndPassword("xxxxxxx","xxxxxxx"))
.thenReturn(notNull())
firebaseUser = firebaseMock.currentUser!!
// NOTE: this assertion will fail as the mocked class will always return null and not the actual value
assertNotNull(firebaseUser)
}