kotlin + aws лямбда, требующая пустого конструктора - PullRequest
0 голосов
/ 26 октября 2018

У меня есть следующий класс, написанный на Kotlin + Guice, который вызывается с помощью лямбды

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

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

Это прекрасно работает для модульного тестирования, но для лямбды требуется, чтобы в классе был пустой конструктор.

Я могу преобразовать этот же класс в пустой конструктор, выполнив следующее:

class LambdaProcessor {

    @Inject lateinit var s3Util: S3Util

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

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

Этот код теперь отлично работает на лямбде, но я больше не могу смоделировать s3Util в своих модульных тестах, потому что метод init получаетзвонил.

Как я могу заставить оба сценария работать вместе?

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

В 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()
    }
}
0 голосов
/ 26 октября 2018

Вы всегда можете объявить вторичные конструкторы .Однако все они должны вызывать первичный конструктор, поэтому есть хитрость, чтобы сделать его private и соответствующим образом обработать аргументы в блоке инициализации.

Я не использую 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()
    }
}
...