I have a challenge with a class which I want to test but inside the class other objects will be created.
This simple example shows the issue.
class A {
val b: B
init() {
b = B()
}
}
It's just an example and I know that dependency injection would help. But in real life it's a very complex class which can not be changed easily.
My idea was to use mockkConstructor
. But it does not the trick.
fun `test construction`() {
mockkConstructor(B::class)
every { anyConstructed<B>() } returns mockk<B>()
val a = A()
}
Unfortunately, it does not compile. Error: Missing mocked calls inside every { ... } block: make sure the object inside the block is a mock
I tried it this way
fun `test construction`() {
mockkConstructor(B::class)
every { A() } returns mockk<B>()
val a = A()
}
But this way it calls the real constructor of A and also the real constructor of B in the init method of A.
Does anybody know if it's possible to solve it this way or similar?
CodePudding user response:
So I made a test for these example classes:
class A {
val b: B
init {
b = B()
}
}
class B {
fun getA(): String {
return "B"
}
}
Test:
@Test
fun test() {
mockkConstructor(A::class)
val b = mockk<B>()
every { anyConstructed<A>().b } returns b
every { b.getA() } returns "MOCKK"
val a = A()
Assert.assertEquals("MOCKK", a.b.getA())
}
CodePudding user response:
Your attempt to mock B()
to return a mock of B
is completely redundant after calling mockkConstructor(B::class)
which already makes the constructor of B
return a prototype mock denoted by anyConstructed<B>()
.
This means, you only need anyConstructed<B>()
to specify the behaviour of calls to that mock, e.g.
every { anyConstructed<B>().someFunctionCall() } returns 1
See MockK documentation: Constructor mocks for more details.