使用 Guice DI 的黄瓜测试无法找到命名注释

问题描述 投票:0回答:0

我一直在尝试使用 Guice 使用 Cucumber 和 DI 添加集成测试。我有以下目录设置

src/main/kotlin/
\_ com.mypackage.tests
   \_ api/ApiGatewayHttpClient.kt
   \_ cucumber
      \_ api
         \_ ApiInfraTestsModule.kt
      \_ CucumberInjectorSource.kt
      \_ InfraTestsModule.kt
   \_ steps
      \_ EdgeApiSteps.kt

ApiInfraTestsModule.kt
写法如下:

class ApiInfraTestsModule : AbstractModule() {

    private val ROLE_ARN_FORMATTER = "arn:aws:iam::%s:role/%s"

    @Provides
    @Singleton
    fun providesCloudFormationExportsExtractor(): BiFunction<String, String, String> {
        return BiFunction { region: String, exportName: String ->
            // some CloudFormation logic, return export value
        }
    }

    @Provides
    @Singleton
    @Named(EDGE_API_ENDPOINT)
    fun providesEdgeApiEndpoint(
        cloudFormationExportsExtractor: BiFunction<String, String, String>
    ): String {
        val region = Environment.region
        return cloudFormationExportsExtractor.apply(
            region, EDGE_API_ENDPOINT_EXPORT_NAME
        )
    }

    @Provides
    @Singleton
    @Named(EDGE_API_UNAUTHORIZED_CREDENTIALS_PROVIDER)
    fun providesApiUnauthorizedCredentialsProvider(
        // this param is supposed to be injected via `InfraTestsModule.kt`
        awsCredentialsProvider: BiFunction<String, String, AwsCredentialsProvider>
    ): AwsCredentialsProvider {
        val region = Environment.region
        val roleArn = String.format(
            ROLE_ARN_FORMATTER,
            Environment.plantFloorAccountId,
            Environment.unauthorizedEdgeProvisioningRoleName
        )
        return awsCredentialsProvider.apply(region, roleArn)
    }

    @Provides
    @Singleton
    @Named(EDGE_API_UNAUTHORIZED_CLIENT)
    fun providesEdgeApiUnAuthorizedClient(
        @Named(EDGE_API_UNAUTHORIZED_CREDENTIALS_PROVIDER)
        credentialsProvider: AwsCredentialsProvider
    ): ApiGatewayHttpClient {
        return ApiGatewayHttpClient(
            Region.of(Environment.region),credentialsProvider
        )
    }
}

EdgeApiSteps.kt
写成:

class EdgeApiSteps @Inject constructor(
    private val testContext: TestContext,
    @Named(EDGE_API_ENDPOINT)
    private val endpoint: String,
    @Named(EDGE_API_UNAUTHORIZED_CLIENT)
    private val unauthorizedApiClient: ApiGatewayHttpClient
) {

    @When("Provisioning API is called with unauthorized client")
    fun executeUnauthorizedApiCall() {
        val response = unauthorizedApiClient.get(endpoint)
        testContext.apiResponseStatus = response.httpResponse().statusCode()
    }
}

当我运行这些测试时,命名注释的依赖注入失败并出现以下错误:

Failed scenarios:
file:////features/security/api/EdgeApi.feature:2 # Provisioning API call with unauthorized principal should fail

1 Scenarios (1 failed)
2 Steps (1 failed, 1 skipped)
0m0.663s


com.google.inject.ConfigurationException: Guice configuration errors:

1) [Guice/MissingImplementation]: No implementation for ApiGatewayHttpClient annotated with @Named(value="EdgeApiUnauthorizedClient") was bound.

Requested by:
1  : EdgeApiSteps.<init>(EdgeApiSteps.kt:11)
      \_ for 3rd parameter
     while locating EdgeApiSteps

Learn more:
  https://github.com/google/guice/wiki/MISSING_IMPLEMENTATION

2) [Guice/MissingImplementation]: No implementation for String annotated with @Named(value="EdgeApi") was bound.

Requested by:
1  : EdgeApiSteps.<init>(EdgeApiSteps.kt:11)
      \_ for 2nd parameter
     while locating EdgeApiSteps

Learn more:
  https://github.com/google/guice/wiki/MISSING_IMPLEMENTATION

2 errors

我看过很多 Guice 示例,似乎 Guice for Kotlin 支持 @Named 注入。但是我根本无法完成这项工作。我不确定 Cucumber 是否能够找到 Guice 模块。我什至剥离了模块,只提供一个 @Named 字符串参数,但它也失败了,并出现了同样的“无实现绑定”错误。

我已经尝试对上述类进行构造函数注入、方法注入、字段注入,但除了上述错误外,这些都没有导致任何结果。

kotlin dependency-injection cucumber integration-testing guice
© www.soinside.com 2019 - 2024. All rights reserved.