hi everybody, im using mockk for mocking the follo...
# announcements
a
hi everybody, im using mockk for mocking the following test fails on the second assertion (returned value is 1 instead of 2). why?
Copy code
class Test {

    @test
    internal fun name() {
        val mock = mockk<Logic>()
        every { mock.doSth() } returns 2
        mock.doSth() shouldBe 2

        val obj = object : HasLogic {}
        obj.doSth() shouldBe 2
    }
}

interface HasLogic {
    fun doSth() = Logic.doSth()
}

object Logic {
    fun doSth() = 1
}
w
You need to use triple backticks to format multiline code 🙂 ` ``` `
a
thx just fixed it
w
Anyway it doesn’t work, because when you’re mocking
Logic
by doing
val mock = mockk<Logic>()
it’s only
mock
variable which, well, is a mock.
mockk<Logic>()
does not change the
object Logic
that you define
a
how can i mock all instances?
w
and since
HasLogic
interface uses
Logic
object directly, and not your mock, it uses real implementation
a
im coming from jmockit and there this would work
w
im coming from jmockit and there this would work
The difference is
Logic.doSth
is not a static method call — it’s a method declared on a
Logic
singleton instance. If you really need and want static methods, you should drop
object Logic
declaration whatsoever. Top-level functions are static jvm methods
Maybe adding
@JvmStatic
would works as well, but I wouldn’t know. Either way you wouldn’t me mocking the entire
Logic
object, rather each function separately, I guess? Not really sure how to help here, since generally what you should do for testability is to inject the dependencies into the objects you’re testing
a
hmmm...i just tried @jvmstatic that gives a compilation error. i will further investigate but i assume there must be a solution, otherwise it would be a big drawback...anyways thank you
found the answer
Copy code
class Test {

    @Test
    internal fun name() {
        mockkObject(Logic)
        every { Logic.doSth() } returns 2

        val obj = object : HasLogic {}
        obj.doSth() shouldBe 2
    }
}

interface HasLogic {
    fun doSth() = Logic.doSth()
}

object Logic {

    fun doSth() = 1
}
w
Interesting. What would happen if you didn’t write
val mock = mockkObject(Logic)
?
Anyway that makes sense if
mockk
library works like that. I’m not using so I wasn’t very helpful 😐
a
works without the val assignment too will fix it
j
So that's sorted out the how, but the why remains. You've just tested your mock implementation. Seems odd...
Usually mocks are handy for collaborators of a thing that's being tested not the implementation of it.
a
well, i guess its a corner case. if
Logic.doSth()
is an expensive operation, which is tested in its own unit test, i think it can make sense to only verify its called to save runtime