我有以下用Kotlin + Guice编写的类,该类通过lambda调用
class LambdaProcessor @Inject constructor(private val s3Util: S3Util) {
fun lambdaInvokesThisMethod() {
s3Util.DoSomething()
}
}
这对于单元测试非常有用,但是lambda要求该类具有一个空的构造函数。
我可以通过执行以下操作将同一类转换为空的构造函数:
class LambdaProcessor {
@Inject lateinit var s3Util: S3Util
init {
Guice.createInjector(GuiceDependencyInjector()).injectMembers(this)
}
fun lambdaInvokesThisMethod() {
s3Util.DoSomething()
}
}
该代码现在在lambda上运行良好,但是由于调用了init方法,因此我无法再在单元测试中模拟s3Util。
如何使两种方案一起工作?
答案 0 :(得分:0)
您始终可以声明辅助constructors。但是,它们所有人都需要调用主构造函数,因此有一个技巧可以使其private
并相应地处理init块中的参数。
我不使用Guice
,但是您可以尝试执行以下操作:
class LambdaProcessor private constructor(s3Util: S3Util?){
@Inject
lateinit var s3Util : S3Util
init{
s3Util?.let { this.s3Util = it }
}
// passes null to primary constructor, leaving field uninitalized
constructor() : this(null){
Guice.createInjector(GuiceDependencyInjector()).injectMembers(this)
}
// passes non-null to primary constructor initializing the field (cast to nullable needed to match primary signature)
constructor(s3Util: S3Util) : this(s3Util as S3Util?)
fun lambdaInvokesThisMethod() {
s3Util.DoSomething()
}
}
答案 1 :(得分:0)
在Kotlin中,如果您有默认构造函数,则所有其他构造函数必须都调用默认值。但是,您可以没有的多个构造函数为默认构造函数。这是我们使用的最终代码。
class LambdaProcessor {
@Inject private lateinit var s3Util: S3Util
/**
* Lambda calls the no-arg constructor, use our IoC library to initialize our dependencies
*/
constructor() {
Guice.createInjector(GuiceDependencyInjector()).injectMembers(this)
}
/*
* Unit-testing constructor
*/
constructor(s3Util: S3Util) {
this.s3Util = s3Util
}
fun lambdaInvokesThisMethod() {
s3Util.DoSomething()
}
}