I'd like to mock out collaborators as documented here with my MicronautLambdaHandler
application, though if you just instantiate MicronautLambdaHandler
by calling its constructor, it apparently won't pick up anything from your test context.
Specifically, this doesn't work as expected:
import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder
import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext
import com.amazonaws.services.lambda.runtime.Context
import com.fasterxml.jackson.databind.ObjectMapper
import io.micronaut.context.ApplicationContext
import io.micronaut.context.ApplicationContextBuilder
import io.micronaut.context.annotation.Factory
import io.micronaut.context.env.Environment
import io.micronaut.http.HttpHeaders
import io.micronaut.http.HttpMethod
import io.micronaut.http.HttpStatus
import io.micronaut.http.MediaType
import org.junit.jupiter.api.Test
import io.micronaut.function.aws.proxy.MicronautLambdaHandler
import io.micronaut.security.authentication.AuthenticationException
import io.micronaut.security.authentication.AuthenticationFailed
import io.micronaut.security.authentication.AuthenticationProvider
import io.micronaut.security.authentication.AuthenticationResponse
import io.micronaut.test.annotation.MockBean
import io.micronaut.test.extensions.junit5.annotation.MicronautTest
import io.mockk.every
import io.mockk.mockk
import io.reactivex.Maybe
import org.assertj.core.api.Assertions
import org.assertj.core.api.Assertions.assertThat
import org.reactivestreams.Publisher
import java.lang.RuntimeException
import javax.inject.Inject
@MicronautTest
class ManualInstantiationTest {
@Inject
lateinit var objectMapper: ObjectMapper
@Inject
lateinit var authenticationProvider: AuthenticationProvider
@MockBean(AuthenticationProvider::class)
fun authenticationProviderMock() = mockk<AuthenticationProvider>()
@Test
fun testLoginHandler() {
every { authenticationProvider.authenticate(any(), any()) } answers {
Maybe.error<AuthenticationResponse>(
AuthenticationException(
AuthenticationFailed("Incorrect password")
)
).toFlowable()
}
val handler = MicronautLambdaHandler()
val loginRequest = Registration("username", "password")
val json = objectMapper.writeValueAsString(loginRequest)
val request = AwsProxyRequestBuilder("/login", HttpMethod.POST.toString())
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON)
.body(json)
.build()
val lambdaContext: Context = MockLambdaContext()
// this.authenticationProvider is never used
val response = handler.handleRequest(request, lambdaContext)
}
}
I've also tried @Inject
ing a field of type MicronautLambdaHandler
, but that fails because no bean is registered of that type.