How to check if a method was not invoked with mockk?

22.7k views Asked by At

I need to check if a method was not invoked in my unit tests. This is an example test I did that checks if the method was invoked and it works perfectly fine:

@Test
fun viewModel_selectDifferentFilter_dispatchRefreshAction() {
    val selectedFilter = FilterFactory.make()
    val event = GroceriesAisleFiltersUiEvent.SelectFilter(
        filter = selectedFilter,
        refreshListAction = mockk()
    )
    every { event.refreshListAction(selectedFilter) } just runs
    viewModel.dispatchViewAction(event)
    verify { event.refreshListAction(selectedFilter) }
}

For that I'm using the mockk's verify function to check if the method is being invoked.

Is there a way to check, using mockk, that this method has not been invoked? In short I need to complete the code below with this check in place of the comment:

@Test
fun viewModel_selectSameFilter_notDispatchRefreshAction() {
    val selectedFilter = viewModel.viewState.value.selectedFilter
    val event = GroceriesAisleFiltersUiEvent.SelectFilter(
        filter = selectedFilter,
        refreshListAction = mockk()
    )
    every { event.refreshListAction(selectedFilter) } just runs
    viewModel.dispatchViewAction(event)
    // TODO: verify if method's not invoked
}
2

There are 2 answers

5
Karsten Gabriel On BEST ANSWER

If you want to verify that your method was not called, you can verify that it was called exactly 0 times:

verify(exactly = 0) { event.refreshListAction(any()) } 

Or, in this case where your event.refreshListAction is the mock, you can equivalently write the following to verify that the mock was not called at all:

verify { event.refreshListAction wasNot Called }

EDIT

It seems that the mock in the question being itself a function (or something else with an invoke operator function) leads to a lot of confusion. For the difference between verify(exactly = 0) and a verify with wasNot Called, refer to this post, where the mock is a simple object.

0
MeLean On

I tried with verify { mockObj.myMethod(any()) wasNot called } and the test failed even when the method of the mock is not called. Then read the comments and saw that one from @Johan Paul I will try to add more explanation:

If you want to assert that a particular method is not called you should sue:

verify(exactly = 0) { mockObj.myMethod(any()) } 

When you need to assert that the mock is not called at all, us should use:

verify { mockObj wasNot called }

This is applicable only if the mockObj is the mocked object it self. Like this:

 val mockObj = mockk() // or mockk(relaxed = true)

In your case answer given by Karsten Gabriel, works because it refers to the mock.