我正在编写一个集成测试,我使用 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 {})