使用 mockito 模拟 firebase 用户时出错
getting error mocking firebase user with mockito
我正在尝试模拟一个 firebase 用户来为我的测试提供它,我模拟了 firebase 身份验证 class 从中我得到了当前登录用户的 uid 但对于某些人它一直在抛出同样的错误,我将不胜感激你们的帮助
- 这是我的生产代码
private fun getUserProfileInfo(){
val db = ServiceLocator.reference
val child = db.child("Users")
val user = ServiceLocator.firebaseUser
val value = child.child(user!!.uid)
value.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if(snapshot.exists()){
val model = snapshot.getValue(ProfileModel::class.java)
userName = model!!.firstName
userPic = model.profilePicUrl
}
}
override fun onCancelled(error: DatabaseError) {
}
})
}
- 这是我的测试代码
@Test
fun testCaseProfileInfo(){
val firebaseUserMock = mock(FirebaseUser::class.java)
val firebaseMock = mock(FirebaseAuth::class.java)
val databaseMock = mock(DatabaseReference::class.java)
ServiceLocator.firebaseAuth = firebaseMock
ServiceLocator.firebaseUser = firebaseUserMock
ServiceLocator.reference = databaseMock
doReturn(firebaseUserMock).`when`(firebaseMock).currentUser
val uid = doReturn("123").`when`(firebaseMock).uid // error here
doReturn(databaseMock.child("Users")
.child(uid!!))
.`when`(databaseMock).get()
}
- 这是我的服务定位器Class
object ServiceLocator {
var firebaseAuth = FirebaseAuth.getInstance()
var reference=FirebaseDatabase.getInstance(Utils.DATABASE_URL).reference
}
- 生成错误(更新后)
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.revert.journey.app.chatui.FriendsRequestActivityTest.testCaseProfileInfo
- 快速更新
@Test
fun testCaseProfileInfo(){
val userMock = mock(FirebaseUser::class.java)
val firebaseMock = mock(FirebaseAuth::class.java)
val databaseMock = mock(DatabaseReference::class.java)
ServiceLocator.firebaseAuth = firebaseMock
ServiceLocator.firebaseUser = userMock
ServiceLocator.reference = databaseMock
doReturn(userMock).`when`(firebaseMock).currentUser
doReturn("123").`when`(userMock)!!.uid
doReturn(databaseMock
.child("Users")
.child("123")) // ( null pointer exception on this string)..
.`when`(databaseMock).get()
}
您还需要从 FirebaseAuth 模拟 returned 用户,像这样
val userMock = mock(FirebaseUser::class.java)
doReturn(userMock).`when`(firebaseMock).currentUser
doReturn("123").`when`(userMock).uid
如果将生产代码拆分成更多的步骤(像这样),您可能会看到 currentUser
为 null
val db = ServiceLocator.reference
val child = db.child("Users")
val user = ServiceLocator.firebaseAuth.currentUser
val uid = user?.uid ?: return
val value = child.child(uid)
使用 mocked classes 时要记住的重要一点是 all 它们的方法将 return null 除非你特别设置 return为了他们。
要完整模拟上述调用,您需要以下模拟
如果您希望您的方法可调用,则需要以下模拟。您的测试方法 根本不与 Firebase 交互 - 它是假的 class (模拟),因此您必须明确告诉它 return 当您调用方法或从中获取属性。您的测试目标是定义这些 return 值,以便从您可以测试的方法中获得一些有用的操作。
@Test
fun testCaseProfileInfo(){
val firebaseMock = mock(FirebaseAuth::class.java)
val databaseMock = mock(DatabaseReference::class.java)
val userMock = mock(FirebaseUser::class.java)
val childMock = mock(Reference::class.java)
ServiceLocator.firebaseAuth = firebaseMock
ServiceLocator.reference = databaseMock
// Tell the firebaseMock what to return when
// you call "currentUser"
doReturn(userMock).`when`(firebaseMock).currentUser
// Tell "userMock" to return "123" when you call
// currentUser.uid in your production method
doReturn("123").`when`(userMock).uid
// Tell the database mock what to return when
// you call db.child("Users")
doReturn(childMock).`when`(databaseMock).child("Users")
// Tell the users mock what to return when you
// call db.child(uid)
doReturn(childMock).`when`.usersMock("123")
// Method should now be callable, but adding a listener for the event would be good to test
}
对于更完整的示例,请考虑使用以下方法获取用户 ID(如果他们已登录),您希望使用 mock 进行测试。
fun getUID(): String? {
val uid = ServiceLocator.firebaseAuth.currentUser?.uid
return uid
}
您可以按如下方式为此编写测试
@Test
fun testUserNotLoggedIn(){
val firebaseMock = mock(FirebaseAuth::class.java)
ServiceLocator.firebaseAuth = firebaseMock
doReturn(null).`when`(firebaseMock).currentUser
assertNull(getUID())
}
@Test
fun testUserLoggedIn(){
val firebaseMock = mock(FirebaseAuth::class.java)
val userMock = mock(FirebaseUser::class.java)
ServiceLocator.firebaseAuth = firebaseMock
doReturn(userMock).`when`(firebaseMock).currentUser
doReturn("123").`when`(userMock).uid
assertEqual("123", getUID())
}
我正在尝试模拟一个 firebase 用户来为我的测试提供它,我模拟了 firebase 身份验证 class 从中我得到了当前登录用户的 uid 但对于某些人它一直在抛出同样的错误,我将不胜感激你们的帮助
- 这是我的生产代码
private fun getUserProfileInfo(){
val db = ServiceLocator.reference
val child = db.child("Users")
val user = ServiceLocator.firebaseUser
val value = child.child(user!!.uid)
value.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if(snapshot.exists()){
val model = snapshot.getValue(ProfileModel::class.java)
userName = model!!.firstName
userPic = model.profilePicUrl
}
}
override fun onCancelled(error: DatabaseError) {
}
})
}
- 这是我的测试代码
@Test
fun testCaseProfileInfo(){
val firebaseUserMock = mock(FirebaseUser::class.java)
val firebaseMock = mock(FirebaseAuth::class.java)
val databaseMock = mock(DatabaseReference::class.java)
ServiceLocator.firebaseAuth = firebaseMock
ServiceLocator.firebaseUser = firebaseUserMock
ServiceLocator.reference = databaseMock
doReturn(firebaseUserMock).`when`(firebaseMock).currentUser
val uid = doReturn("123").`when`(firebaseMock).uid // error here
doReturn(databaseMock.child("Users")
.child(uid!!))
.`when`(databaseMock).get()
}
- 这是我的服务定位器Class
object ServiceLocator {
var firebaseAuth = FirebaseAuth.getInstance()
var reference=FirebaseDatabase.getInstance(Utils.DATABASE_URL).reference
}
- 生成错误(更新后)
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.revert.journey.app.chatui.FriendsRequestActivityTest.testCaseProfileInfo
- 快速更新
@Test
fun testCaseProfileInfo(){
val userMock = mock(FirebaseUser::class.java)
val firebaseMock = mock(FirebaseAuth::class.java)
val databaseMock = mock(DatabaseReference::class.java)
ServiceLocator.firebaseAuth = firebaseMock
ServiceLocator.firebaseUser = userMock
ServiceLocator.reference = databaseMock
doReturn(userMock).`when`(firebaseMock).currentUser
doReturn("123").`when`(userMock)!!.uid
doReturn(databaseMock
.child("Users")
.child("123")) // ( null pointer exception on this string)..
.`when`(databaseMock).get()
}
您还需要从 FirebaseAuth 模拟 returned 用户,像这样
val userMock = mock(FirebaseUser::class.java)
doReturn(userMock).`when`(firebaseMock).currentUser
doReturn("123").`when`(userMock).uid
如果将生产代码拆分成更多的步骤(像这样),您可能会看到 currentUser
为 null
val db = ServiceLocator.reference
val child = db.child("Users")
val user = ServiceLocator.firebaseAuth.currentUser
val uid = user?.uid ?: return
val value = child.child(uid)
使用 mocked classes 时要记住的重要一点是 all 它们的方法将 return null 除非你特别设置 return为了他们。
要完整模拟上述调用,您需要以下模拟
如果您希望您的方法可调用,则需要以下模拟。您的测试方法 根本不与 Firebase 交互 - 它是假的 class (模拟),因此您必须明确告诉它 return 当您调用方法或从中获取属性。您的测试目标是定义这些 return 值,以便从您可以测试的方法中获得一些有用的操作。
@Test
fun testCaseProfileInfo(){
val firebaseMock = mock(FirebaseAuth::class.java)
val databaseMock = mock(DatabaseReference::class.java)
val userMock = mock(FirebaseUser::class.java)
val childMock = mock(Reference::class.java)
ServiceLocator.firebaseAuth = firebaseMock
ServiceLocator.reference = databaseMock
// Tell the firebaseMock what to return when
// you call "currentUser"
doReturn(userMock).`when`(firebaseMock).currentUser
// Tell "userMock" to return "123" when you call
// currentUser.uid in your production method
doReturn("123").`when`(userMock).uid
// Tell the database mock what to return when
// you call db.child("Users")
doReturn(childMock).`when`(databaseMock).child("Users")
// Tell the users mock what to return when you
// call db.child(uid)
doReturn(childMock).`when`.usersMock("123")
// Method should now be callable, but adding a listener for the event would be good to test
}
对于更完整的示例,请考虑使用以下方法获取用户 ID(如果他们已登录),您希望使用 mock 进行测试。
fun getUID(): String? {
val uid = ServiceLocator.firebaseAuth.currentUser?.uid
return uid
}
您可以按如下方式为此编写测试
@Test
fun testUserNotLoggedIn(){
val firebaseMock = mock(FirebaseAuth::class.java)
ServiceLocator.firebaseAuth = firebaseMock
doReturn(null).`when`(firebaseMock).currentUser
assertNull(getUID())
}
@Test
fun testUserLoggedIn(){
val firebaseMock = mock(FirebaseAuth::class.java)
val userMock = mock(FirebaseUser::class.java)
ServiceLocator.firebaseAuth = firebaseMock
doReturn(userMock).`when`(firebaseMock).currentUser
doReturn("123").`when`(userMock).uid
assertEqual("123", getUID())
}