我正在编写集成测试,我使用SparkConsumer
的所有测试使用相同的@BeforeAll
实例。
但是,在每次测试之间,我想传递@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 {})