Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockk: Stubbing same function twice ignores first behaviour

Tags:

kotlin

mockk

I want to provide a null value for all calls with an id >= 100 -- and a concrete Product instance with the captured id for all others:

    every { repoMock.findById(more(100, true)) } returns null
    every { repoMock.findById(capture(idSlot)) } answers { Product(idSlot.captured, "Sample Product", 1.99) }

However the first behaviour is ignored -- for id 1234 the mock returns a Product instance.

I know I can fix it by having an answers{..} block with an if -- but what's going on here? Is the capturing behaviour ruling out all other behaviours?

like image 925
Tom Avatar asked Mar 09 '26 02:03

Tom


1 Answers

It is not the capturing behaviour specifically, but simply the fact that the expression inside the second every matches the same (and more) cases as the first every does.

When you define some behaviour for a combination of a mock object and arguments, you override any previously defined behaviour for the same mock object and arguments. Since capture(idSlot) matches any argument, it does also match arguments >= 100, and therefore, it overrides the behaviour defined in the above line.

But, on the other hand, since the first every is indeed more specific than the second every, the desired behaviour can be achieved by switching the lines:

every { repoMock.findById(capture(idSlot)) } answers { Product(idSlot.captured, "Sample Product", 1.99) }
every { repoMock.findById(more(100, true)) } returns null

Then the second every overrides only the behaviour for a part of all combinations of repoMock and ids, that is, only the ones that are >= 100.

like image 185
Karsten Gabriel Avatar answered Mar 11 '26 18:03

Karsten Gabriel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!