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

2

34

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
}
Thrift answered 30/3, 2022 at 16:23 Comment(0)
K
61

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.

Kenwrick answered 30/3, 2022 at 17:8 Comment(5)
this doesn't work with a mocked navController. Edit: So, for some reason, only the first one works with navController and not the second one.Athenaathenaeum
Can confirm this. First works, second doesn't.Fallon
In the second case it should be using :: event::refreshListActionShifra
verify { event.refreshListAction wasNot called } cannot be used with methods. wasNot can only be used for checking that a mock as a whole was not called. It cannot be used for checking that a method was not called.Middlebreaker
@JohanPaul Yes, please note the line refreshListAction = mockk() in the question. event.refreshListAction is not a method of the mock, but it is the mock.Kenwrick
E
2

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.

Edisonedit answered 19/10, 2023 at 6:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.