kotlin + aws lambda 需要空构造函数

kotlin + aws lambda requiring empty constructor

我有以下 class 用 lambda 调用的 Kotlin+Guice 编写的

class LambdaProcessor @Inject constructor(private val s3Util: S3Util) {

    fun lambdaInvokesThisMethod() {
        s3Util.DoSomething()
    }
}

这非常适合单元测试,但 lambda 要求 class 有一个空的构造函数。

我可以通过这样做将相同的 class 转换为空构造函数:

class LambdaProcessor {

    @Inject lateinit var s3Util: S3Util

    init {
        Guice.createInjector(GuiceDependencyInjector()).injectMembers(this)
    }

    fun lambdaInvokesThisMethod() {
        s3Util.DoSomething()
    }
}

该代码现在在 lambda 上运行良好,但我不能再在我的单元测试中模拟 s3Util,因为调用了 init 方法。

我怎样才能使这两种情况一起工作?

您始终可以声明次要 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()
    }
}

在 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()
    }
}