这是我的整个考试班:
@RunWith(JUnit4::class)
class ExplorerRemoteImplTest {
// Mocks
private val mockDatabase = mock<FirebaseFirestore>(
defaultAnswer = RETURNS_DEEP_STUBS
)
private val mockQuerySnapshot = mock<QuerySnapshot>()
private val mockQuerySnapshotTask = mock<Task<QuerySnapshot>>()
// Class under test
private lateinit var explorerRemoteImpl: ExplorerRemoteImpl
// Others
private val poiList = listOf(TestDataFactory.makePoiRepo(),TestDataFactory.makePoiRepo())
@Before
fun setup(){
//create instance of class under test
explorerRemoteImpl = ExplorerRemoteImpl(mockDatabase)
// Step #1 return the query Task on get().
whenever(mockDatabase.collection(ArgumentMatchers.anyString()).orderBy(ArgumentMatchers.anyString()).get()).thenReturn(mockQuerySnapshotTask)
// Step #2 return a queryTask when registering the listener
whenever(mockQuerySnapshotTask.addOnCompleteListener(anyOrNull()))
.thenReturn(mockQuerySnapshotTask)
// Step #3 task IS successful is stubbed
// Step #4 the results of the task is a QuerySnapshot
whenever(mockQuerySnapshotTask.result).thenReturn(mockQuerySnapshot)
// Step #5 QuerySnapshot = is empty or not is stubbed
// Step #6 when we try to convert snapShot to objects
whenever(mockQuerySnapshot.toObjects(PoiRepository::class.java)).thenReturn(poiList)
}
private fun stubQuerySnapshotIsEmpty(boolean: Boolean){
whenever(mockQuerySnapshot.isEmpty).thenReturn(boolean)
}
private fun stubQueryTaskIsSuccessful(boolean: Boolean){
whenever(mockQuerySnapshotTask.isSuccessful).thenReturn(boolean)
}
@After
fun onEnd(){
Mockito.reset(mockQuerySnapshotTask)
Mockito.reset(mockDatabase)
Mockito.reset(mockQuerySnapshot)
}
@Test
fun getPoisCompletes() {
// GIVEN
stubQueryTaskIsSuccessful(true)
stubQuerySnapshotIsEmpty(false)
val testObserver = explorerRemoteImpl.getPois().test()
// Trigger callback reply
// see: https://fernandocejas.com/2014/04/08/unit-testing-asynchronous-methods-with-mockito/
val captor = argumentCaptor<OnCompleteListener<QuerySnapshot>>()
verify(mockQuerySnapshotTask).addOnCompleteListener(captor.capture())
captor.lastValue.onComplete(mockQuerySnapshotTask)
verify(mockQuerySnapshotTask, times(1)).addOnCompleteListener(anyOrNull())
// THEN
testObserver
.assertNoErrors()
.assertValueCount(1)
.assertComplete()
}
@Test
fun getPoisCompletesOnEmptyQuerySnapshot() {
// GIVEN
stubQueryTaskIsSuccessful(true)
stubQuerySnapshotIsEmpty(true)
val testObserver = explorerRemoteImpl.getPois().test()
// Trigger callback reply
// see: https://fernandocejas.com/2014/04/08/unit-testing-asynchronous-methods-with-mockito/
val captor = argumentCaptor<OnCompleteListener<QuerySnapshot>>()
verify(mockQuerySnapshotTask).addOnCompleteListener(captor.capture())
captor.firstValue.onComplete(mockQuerySnapshotTask)
// THEN
testObserver
.assertNoErrors()
.assertValueCount(0)
.assertComplete()
Mockito.verify(mockQuerySnapshotTask, times(1)).addOnCompleteListener(anyOrNull())
}
@Test
fun getPoisErrorsOnNoSuccessQuerySnapshot() {
// GIVEN
stubQueryTaskIsSuccessful(false)
stubQuerySnapshotIsEmpty(true)
val testObserver = explorerRemoteImpl.getPois().test()
// Trigger callback reply
val captor = argumentCaptor<OnCompleteListener<QuerySnapshot>>()
verify(mockQuerySnapshotTask).addOnCompleteListener(captor.capture())
captor.firstValue.onComplete(mockQuerySnapshotTask)
Mockito.verify(mockQuerySnapshotTask, times(1)).addOnCompleteListener(anyOrNull())
// task Exception not mocked, so unknown is passed via Elvis operator
testObserver.assertError(UnknownError::class.java)
}
}
有3个单元测试,并且分别运行时都通过,但是当我运行整个测试类时,我的第二个和第三个测试失败,并显示以下错误:
Wanted but not invoked:
task.addOnCompleteListener(
<Capturing argument>
);
-> at com.loc8r.seattleexplorer.remote.ExplorerRemoteImplTest.getPoisCompletesOnEmptyQuerySnapshot(ExplorerRemoteImplTest.kt:113)
Actually, there were zero interactions with this mock.
我已尽力解决该问题:
我应该提到我正在使用nhaarman.mockitokotlin2库,它是argumentsCaptor。
有任何线索说明为什么这些测试在单独运行时通过但在作为一个类一起运行时却失败了?
答案 0 :(得分:0)
您是否尝试过避免使用被测试类的单个共享实例(在您的情况下为ExplorerRemoteImpl
?尝试为每个测试方法创建一个新实例。
实际上,我正面临与您上述完全相同的问题,但是由于我尝试测试单例,因此我无法重新实例化我的被测类。
更新: 我已经重构了单例的实现,因此对于测试,我可以为每个测试方法实例化“被测类”。该问题不再发生。