gpt4 book ai didi

android - 为什么我的 Android 单元测试一起运行时失败,但单独运行时通过?

转载 作者:行者123 更新时间:2023-11-29 02:24:48 24 4
gpt4 key购买 nike

这是我的整个测试类:

@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.

我已尽我所能解决问题:

  1. 我将待测试实例化的类移到了@Before 函数中。
  2. 我尝试创建一个 @After 函数并在我的模拟上调用 Mockito.reset。

我应该提到我正在使用 nhaarman.mockitokotlin2 库,它是 argumentCaptor。

关于为什么这些测试在单独运行时通过但在作为一个类一起运行时失败的任何线索?

最佳答案

您是否尝试过避免使用被测类的单个共享实例,在您的案例中是 ExplorerRemoteImpl?尝试为每个测试方法创建一个新实例。

实际上我面临着与您上面描述的完全相同的问题,但我无法重新实例化我的被测类,因为我试图测试一个单例。

更新:我已经重构了我的单例的实现,所以为了测试我可以为每个测试方法实例化被测类。问题不再出现。

关于android - 为什么我的 Android 单元测试一起运行时失败,但单独运行时通过?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52881947/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com