kosi-libs / MocKMP

A mocking processor for Kotlin Multiplatform
https://kosi-libs.org/mockmp
MIT License
183 stars 12 forks source link

Multiple calls to `every{}` doesn't get applied #43

Closed kartik-prakash closed 1 year ago

kartik-prakash commented 1 year ago

It would be nice if the every{} call can be overridden via multiple consecutive calls? Not sure if it can be done straight out of the box though.

For example:

interface Foo {
   fun bar(): Boolean
}

val impl: Foo = MockFoo(mocker);

fun myTest() {
     every { impl.bar() } returns true
     val actual1 = impl.foo() // This will be true

     every { impl.bar() } returns false
     val actual2 = impl.foo() // This is expected to be false
}

Currently with latest version, actual2 will be equal to true, however it would be nice if the return value of bar() get's modified by the second call to every {}. This will help in setting up tests with basic return types in @Before() hook and then modify things as needed in the test.

plusmobileapps commented 1 year ago

I was going crazy trying to figure out why my test wasn't working but this drawback to the library made everything make sense. Hope this gets fixed soon as it is a pretty common practice for any mocking library 😄

SalomonBrys commented 1 year ago

This is not possible the way you are proposing, but the library already offers an API for what you are trying to achieve (documented here]:

val everyBar = every { foo.bar() }

everyBar returns true
val actual1 = foo.bar() // This will be true

everyBar returns false
val actual2 = foo.bar() // This will be false

The reason that this is not possible is that argument constraints are functional, therefore, there is no way to know if multiple mocking calls are the same. Furthermore, it would lead to very complicated cases where some redeclarations would mean override, and some would mean specialization.