我正在编写一个集成测试,我使用 SparkConsumer 的所有测试使用相同的 SparkConsumer 实例 .

但是,在每次测试之间,我想传递不同的模拟实例,其中 @BeforeEach 是在 SparkConsumer 的构造函数中注入的,而不会使 SparkConsumer 的内部变为可变 .

我能想到的更简单的解决方案是将代理实例传递给可以观察当前模拟实例的构造函数 .

我可以使用Kotlin的Delegation feature,但我得出的结论是,它仅用于委托初始化时已知的实例 .

我在研究期间做了三次尝试:

  • 选项A - 通过匿名实例,它可以工作,但它不优雅
SUT = SparkConsumer(PORT, object : IEventsService {
        override fun create(eventRequest: Event.Request)
            = eventsServiceMock.create(eventRequest)
    })
  • 选项B - 通过引用lateinit var:它立即进行评估,然后失败
SUT = SparkConsumer(PORT, object : IEventsService by eventsServiceMock {})
  • 选项C - 由引用lateinit var的Delegate属性:它立即评估属性,但失败
private val eventsServiceMockByLazy: IEventsService by object {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): IEventsService = eventsServiceMock
}
    SUT = SparkConsumer(PORT, object : IEventsService by eventsServiceMockByLazy {})

以下是一些代码:

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class SparkConsumerIntegrationTest {
    val PORT = 28411

    private lateinit var SUT: SparkConsumer
    private lateinit var eventsServiceMock: IEventsService
    private val eventsServiceMockByLazy: IEventsService by object { // For Option C only
        operator fun getValue(thisRef: Any?, property: KProperty<*>): IEventsService = eventsServiceMock
    }

    @BeforeAll
    fun beforeAll() {
        // Option A
        SUT = SparkConsumer(PORT, object : IEventsService {
            override fun create(eventRequest: Event.Request)
                = eventsServiceMock.create(eventRequest)
        })
        // Option B
        SUT = SparkConsumer(PORT, object : IEventsService by eventsServiceMock {})
        // Option C
        SUT = SparkConsumer(PORT, object : IEventsService by eventsServiceMockByLazy {})
    }

    @AfterAll
    fun afterAll() {
        SUT.kill()
    }

    @BeforeEach
    fun setUp() {
        eventsServiceMock = mock { }
    }

    @Test
    fun `should events-create pass`() {
        // S
        val requestObj = Event.Request("Some device", "Some statement")
        eventsServiceMock.stub {
            on {
                create(Event.Request("Some device", "Some statement"))

            }.doReturn(Event.Data("0123", "Some device", "Some statement"))
        }

        // ...
    }

    // ...
}

有没有一种很好的方法可以通过Kotlin中的引用/函数结果在实例上使用类授权功能?

即:像:

SparkConsumer(PORT, object : IEventsService by this::eventsServiceMock {})