1

I have a class like below:

class ViewTrackingFlow : ViewTrackingFlowInterface {
private lateinit var onSuc: (input: Int) -> String
private var itemTrackingFlow: MutableStateFlow<Int> = MutableStateFlow(0)

@OptIn(FlowPreview::class)
override suspend fun init(onSuccess: (index: Int) -> String) {
    this.onSuc = onSuccess
    itemTrackingFlow.debounce(THRESHOLD_MS).distinctUntilChanged().flowOn(Dispatchers.Default)
        .collect { groupCardPosition ->
            onSuc(groupCardPosition)
        }
}

override fun postViewEvent(index: Int?) {
    if (index != null) {
        itemTrackingFlow.value = index
    }
}

}

the init function is called in a fragment with viewLifecycleOwner.lifecycleScope.launch, it works in the fragment, but in the below unit test class, it does not invode the collect function, the unit test class as below:

internal class ViewTrackingFlowTest {
private lateinit var trackingFlow: ViewTrackingFlow

@OptIn(ExperimentalCoroutinesApi::class)
private val testCoroutineScope = TestScope(UnconfinedTestDispatcher())

@Before
fun setUp() {
    trackingFlow = ViewTrackingFlow()

}

@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun testOnPostViewEvent() {
    // Given
    val action = mock<(Int) -> String>()
    val job = testCoroutineScope.launch {
        trackingFlow.init(onSuccess = action)
    }

    // When
    job.run {
        trackingFlow.postViewEvent(5)
    }

    // Then
    verify(action).invoke(5)
}

}

the action is not invoked in the test environment, I tried to put the trackingFlow.postViewEvent(5) in the testCoroutineScope.launch {:

  val job = testCoroutineScope.launch {
        trackingFlow.init(onSuccess = action)
        trackingFlow.postViewEvent(5)
    }

it doesn't work neither, because the init is a suspend function, the postViewEvent will not be called.

I'm quite new to coroutines testing, can anybody help take a look, many thanks!

user3201520
  • 142
  • 1
  • 11

0 Answers0