Reputation: 93
I have a question regarding mockk
.
When using MockK's wasNot called
to check that ClassA
is called, there is a problem that the test fails if it is called in another test even if ClassA
is not called in the current test.
Why is this happening and how can I fix it?
Code:
class ClassA {
fun method(): Int = 1
}
class ClassB(val classA: ClassA, var call: Boolean = true) {
fun method(): Int = if(call) classA.method() else 0
}
class MyTest: FreeSpec({
"Test" - {
val mockClassA = mockk<ClassA>()
val sut = ClassB(mockClassA)
"methodA called" - {
every { mockClassA.method() } returns 1
sut.method()
verify { mockClassA.method() }
}
"methodA not called" - {
every { mockClassA.method() } returns 1
sut.call = false
sut.method()
verify { mockClassA wasNot called } // failed here
}
}
})
Error message:
Verification failed: ClassA(#1) should not be called:
Upvotes: 1
Views: 1847
Reputation: 3662
There are several ways how you can bypass that behavior.
One way would be to just not reuse your mock, but instead create a new one, and and a new sut
for each test. If this would lead to a lot of duplicated code, you can just write helper functions for the setup.
You can define different Isolation Modes for your Kotest test. The default one is SingleInstance
which means that there is one single spec instantiated when running the tests in your test class.
When you change this to InstancePerLeaf
, then for every test leaf in your spec, a new spec instance is created. You can define that at different locations, for instance it the global ProjectConfig
:
class ProjectConfig : AbstractProjectConfig() {
override val isolationMode = IsolationMode.InstancePerLeaf
}
or locally for your test like this:
class MyTest : FreeSpec({
isolationMode = IsolationMode.InstancePerLeaf
"Test" - {
...
You can clear the internal state of each mock with clearMocks
, or alternatively for all mocks with clearAllMocks
. When you do this after each test, then the verification does not fail due to calls in earlier tests.
You can call it like this:
"methodA called" - {
every { mockClassA.method() } returns 1
sut.method()
verify { mockClassA.method() }
clearMocks(mockClassA)
}
or for all tests like this:
afterAny {
clearMocks(mockClassA)
}
"methodA called" - {
...
Upvotes: 1