'Android Kotlin unit test - Exception in thread "Test worker @coroutine#1" java.lang.NullPointerException

Already referred this very similar issue.

I am trying to write my first coroutine test.

Getting this error,

Exception in thread "Test worker @coroutine#1"

java.lang.NullPointerException at <app_package_name>.data.source.usecase.GetSourcesCountUseCase.invoke(GetSourcesCountUseCase.kt:10)

Unit Test code

class AddTransactionScreenViewModelImplTest {
    @get:Rule
    val mainDispatcherRule = MainDispatcherRule()

    private val dataStore: MyDataStore = mock()
    private val getCategoriesUseCase: GetCategoriesUseCase = mock()
    private val getSourcesUseCase: GetSourcesUseCase = mock()
    private val getTitleSuggestionsUseCase: GetTitleSuggestionsUseCase = mock()
    private val navigationManager: NavigationManager = mock()
    private val dispatcherProvider: DispatcherProvider = TestDispatcherProviderImpl(
        testDispatcher = mainDispatcherRule.testDispatcher,
    )
    private val getSourcesCountUseCase: GetSourcesCountUseCase = mock()
    private val insertTransactionUseCase: InsertTransactionUseCase = mock()
    private val updateSourcesUseCase: UpdateSourcesUseCase = mock()

    private lateinit var addTransactionScreenViewModel: AddTransactionScreenViewModel

    @Before
    fun setUp() {
        addTransactionScreenViewModel = AddTransactionScreenViewModelImpl(
            dataStore = dataStore,
            getCategoriesUseCase = getCategoriesUseCase,
            getSourcesUseCase = getSourcesUseCase,
            getTitleSuggestionsUseCase = getTitleSuggestionsUseCase,
            navigationManager = navigationManager,
            dispatcherProvider = dispatcherProvider,
            getSourcesCountUseCase = getSourcesCountUseCase,
            insertTransactionUseCase = insertTransactionUseCase,
            updateSourcesUseCase = updateSourcesUseCase,
        )
    }

    @After
    fun tearDown() {
    }

    @Test
    fun getTransactionTypesForNewTransaction(): Unit = runTest {
        whenever(
            getSourcesCountUseCase.invoke()
        ).thenReturn(1)
        whenever(
            getSourcesUseCase.invoke()
        ).thenReturn(
            flow {
                emptyList<Source>()
            },
        )
        whenever(
            getCategoriesUseCase.invoke()
        ).thenReturn(
            flow {
                emptyList<Category>()
            },
        )

        val result: List<TransactionType> = addTransactionScreenViewModel
            .transactionTypesForNewTransaction.first()
        Assert.assertEquals(
            arrayOf(
                TransactionType.INCOME,
                TransactionType.EXPENSE,
                TransactionType.TRANSFER
            ),
            result,
        )
    }
}

Code I am testing

override val transactionTypesForNewTransaction: StateFlow<List<TransactionType>> = flow {
        val sourceCount = getSourcesCountUseCase()
        val transactionTypesForNewTransaction = TransactionType.values().filter {
            if (sourceCount > 1) {
                it != TransactionType.ADJUSTMENT
            } else {
                it != TransactionType.ADJUSTMENT && it != TransactionType.TRANSFER
            }
        }
        emit(
            value = transactionTypesForNewTransaction,
        )
    }.defaultListStateIn()

MainDispatcherRule (Source)

class MainDispatcherRule(
    val testDispatcher: TestDispatcher = UnconfinedTestDispatcher(),
) : TestWatcher() {
    override fun starting(description: Description) {
        Dispatchers.setMain(testDispatcher)
    }

    override fun finished(description: Description) {
        Dispatchers.resetMain()
    }
}

TestDispatcherProviderImpl

class TestDispatcherProviderImpl(
    testDispatcher: TestDispatcher,
) : DispatcherProvider {
    override val main: CoroutineDispatcher = testDispatcher
    override val io: CoroutineDispatcher = testDispatcher
    override val default: CoroutineDispatcher = testDispatcher
    override val unconfined: CoroutineDispatcher = testDispatcher
}

DispatcherProvider

interface DispatcherProvider {
    val main: CoroutineDispatcher
    val io: CoroutineDispatcher
    val default: CoroutineDispatcher
    val unconfined: CoroutineDispatcher
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source