Android Firebase Junit4 模拟数据库。如何模拟数据库children?
Android Firebase Junit4 mocking database. How to mock database children?
需要一些帮助来测试我的应用程序。
我想验证视图模型的乐趣 writeNewTask()。它必须将 Task object 添加到名为 tasks 和个人 id[ 的 parents 下的数据库中=27=] 每个任务。
fun writeNewTask(name: String?, orphanage: String?) {
val id = database.push().key!!
val task = Task(id, name, orphanage)
database.child("tasks").child(id).setValue(task)
}
我正在使用 PowerMock。所以,这就是我的测试结果
@RunWith(PowerMockRunner::class)
@PowerMockRunnerDelegate(JUnit4::class)
@PrepareForTest(FirebaseDatabase::class, AddTaskViewModel::class, DatabaseReference::class)
@PowerMockIgnore("org.mockito.*", "org.robolectric.*", "android.*", "androidx.*")
class AddTaskViewModelTest {
@Mock
lateinit var mockedDatabase: FirebaseDatabase
@Mock
lateinit var databaseReference: DatabaseReference
@Mock
lateinit var viewModel: AddTaskViewModel
@Before
fun before() {
viewModel = PowerMockito.mock(AddTaskViewModel::class.java)
databaseReference = PowerMockito.mock(DatabaseReference::class.java)
PowerMockito.mockStatic(AddTaskViewModel::class.java)
PowerMockito.mockStatic(DatabaseReference::class.java)
PowerMockito.mockStatic(FirebaseDatabase::class.java)
`when`(FirebaseDatabase.getInstance()).thenReturn(mockedDatabase)
mockedDatabase = PowerMockito.mock(FirebaseDatabase::class.java)
`when`(mockedDatabase.reference).thenReturn(databaseReference)
}
@Test
fun writeNewTaskTest() {
val id = "1"
`when`(databaseReference.key).thenReturn(id)
val name = "name"
val orphanage = "orphanage"
val task = Task(id, name, orphanage)
viewModel.writeNewTask(name, orphanage)
verify(databaseReference)
.child("tasks")
.child(id)
.setValue(task)
}
}
我发现了这个错误。调试后我发现 child("tasks") 是 null
databaseReference.child("tasks");
-> at com.example.application.viewModel.AddTaskViewModelTest.writeNewTaskTest(AddTaskViewModelTest.kt:59)
Actually, there were zero interactions with this mock.
Wanted but not invoked:
databaseReference.child("tasks");
-> at com.example.application.viewModel.AddTaskViewModelTest.writeNewTaskTest(AddTaskViewModelTest.kt:59)
Actually, there were zero interactions with this mock.
发生这种情况是因为您对数据库的引用与您在 ViewModel 中的引用不同。所以让我们假设你有一个 ViewModel,它在它的构造函数中获取一个数据库:
class AddTaskViewModel(private val database: FirebaseDatabase): ViewModel()
因此,要测试您的 ViewModel,您需要创建它的实例,而不是模拟它。在您的代码中应该如下所示:
@Before
fun before() {
databaseReference = mock(DatabaseReference::class.java)
mockedDatabase = mock(FirebaseDatabase::class.java)
`when`(mockedDatabase.reference).thenReturn(databaseReference)
viewModel = AddTaskViewModel(mockedDatabase)
}
另外你不需要PowerMockito来测试这个,Mockito本身就足够了
需要一些帮助来测试我的应用程序。 我想验证视图模型的乐趣 writeNewTask()。它必须将 Task object 添加到名为 tasks 和个人 id[ 的 parents 下的数据库中=27=] 每个任务。
fun writeNewTask(name: String?, orphanage: String?) {
val id = database.push().key!!
val task = Task(id, name, orphanage)
database.child("tasks").child(id).setValue(task)
}
我正在使用 PowerMock。所以,这就是我的测试结果
@RunWith(PowerMockRunner::class)
@PowerMockRunnerDelegate(JUnit4::class)
@PrepareForTest(FirebaseDatabase::class, AddTaskViewModel::class, DatabaseReference::class)
@PowerMockIgnore("org.mockito.*", "org.robolectric.*", "android.*", "androidx.*")
class AddTaskViewModelTest {
@Mock
lateinit var mockedDatabase: FirebaseDatabase
@Mock
lateinit var databaseReference: DatabaseReference
@Mock
lateinit var viewModel: AddTaskViewModel
@Before
fun before() {
viewModel = PowerMockito.mock(AddTaskViewModel::class.java)
databaseReference = PowerMockito.mock(DatabaseReference::class.java)
PowerMockito.mockStatic(AddTaskViewModel::class.java)
PowerMockito.mockStatic(DatabaseReference::class.java)
PowerMockito.mockStatic(FirebaseDatabase::class.java)
`when`(FirebaseDatabase.getInstance()).thenReturn(mockedDatabase)
mockedDatabase = PowerMockito.mock(FirebaseDatabase::class.java)
`when`(mockedDatabase.reference).thenReturn(databaseReference)
}
@Test
fun writeNewTaskTest() {
val id = "1"
`when`(databaseReference.key).thenReturn(id)
val name = "name"
val orphanage = "orphanage"
val task = Task(id, name, orphanage)
viewModel.writeNewTask(name, orphanage)
verify(databaseReference)
.child("tasks")
.child(id)
.setValue(task)
}
}
我发现了这个错误。调试后我发现 child("tasks") 是 null
databaseReference.child("tasks");
-> at com.example.application.viewModel.AddTaskViewModelTest.writeNewTaskTest(AddTaskViewModelTest.kt:59)
Actually, there were zero interactions with this mock.
Wanted but not invoked:
databaseReference.child("tasks");
-> at com.example.application.viewModel.AddTaskViewModelTest.writeNewTaskTest(AddTaskViewModelTest.kt:59)
Actually, there were zero interactions with this mock.
发生这种情况是因为您对数据库的引用与您在 ViewModel 中的引用不同。所以让我们假设你有一个 ViewModel,它在它的构造函数中获取一个数据库:
class AddTaskViewModel(private val database: FirebaseDatabase): ViewModel()
因此,要测试您的 ViewModel,您需要创建它的实例,而不是模拟它。在您的代码中应该如下所示:
@Before
fun before() {
databaseReference = mock(DatabaseReference::class.java)
mockedDatabase = mock(FirebaseDatabase::class.java)
`when`(mockedDatabase.reference).thenReturn(databaseReference)
viewModel = AddTaskViewModel(mockedDatabase)
}
另外你不需要PowerMockito来测试这个,Mockito本身就足够了