8

Spring Boot allows to inject a list of all implementations of an interface (SomeComponent) as List into another component (SomeOtherComponent), e.g.

@Component
interface SomeComponent
@Component
class SomeComponentImpl0 : SomeComponent
@Component
class SomeComponentImpl1 : SomeComponent
class SomeOtherComponent {
    @Autowired
    lateinit var impls: List<SomeComponent>
}

How can I inject mocks for the implementations using MockK annotations? In

import io.mockk.MockKAnnotations
import io.mockk.impl.annotations.InjectMockKs
import io.mockk.impl.annotations.MockK
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class SomeOtherComponentTest {
    @MockK
    lateinit var someComponentImpl0: SomeComponentImpl0

    @MockK
    lateinit var someComponentImpl1: SomeComponentImpl1

    @InjectMockKs
    lateinit var instance: SomeOtherComponent

    @BeforeEach
    fun setup() {
        MockKAnnotations.init(this)
    }

    @Test
    fun testSomething() {
        println(instance.impls.toString())
    }
}

I'm getting either

io.mockk.MockKException: 
No matching constructors found:
constructor(impls : kotlin.collections.List<de.richtercloud.inject.mocks.foor.list.of.impl.SomeComponent> = <not able to lookup>)
        at de.richtercloud.inject.mocks.foor.list.of.impl.SomeOtherComponentTest.setup(SomeOtherComponentTest.kt:40)

if I'm using constructor injecction and

kotlin.UninitializedPropertyAccessException: lateinit property impls has not been initialized
        at de.richtercloud.inject.mocks.foor.list.of.impl.SomeOtherComponentTest.testSomething(SomeOtherComponentTest.kt:26)

if I'm using an @Autowired var property in the class.

I'm using 1.3.50 through Maven 3.6 and MockK 1.9.3.

Kalle Richter
  • 8,008
  • 26
  • 77
  • 177

2 Answers2

6

Add @ExtendWith(MockKExtension::class) above your Test class to make @InjectMokKs work.

Fabi D
  • 71
  • 1
  • 6
-3

I had the same problem here. It worked when I removed lateinit from the component being tested, and instantiated it on declaration.

For example, changed:

    @InjectMockKs
    lateinit var instance: SomeOtherComponent

to:

    @InjectMockKs
    var instance = SomeOtherComponent()