You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus DynamoDB测试初始化:LocalStack表创建与清理方案咨询

在Quarkus测试中用LocalStack管理DynamoDB表的可行方案

针对你遇到的QuarkusTestResourceLifecycleManager无法使用CDI注入、客户端读取不到配置的问题,这里提供两种实用解决方案:

方案一:Testcontainers LocalStack + Quarkus测试扩展(推荐)

这个方案无需手动管理LocalStack生命周期,Quarkus会自动配置DynamoDB客户端,CDI注入正常可用。

步骤1:添加依赖

Maven项目在pom.xml中添加:

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>localstack</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-testcontainers</artifactId>
    <scope>test</scope>
</dependency>

步骤2:配置测试环境

在src/test/resources/application.properties中添加:

# 自动引用Testcontainers暴露的LocalStack环境变量
quarkus.dynamodb.endpoint-override=${localstack.dynamodb.url}
quarkus.dynamodb.aws.region=${localstack.region}
quarkus.dynamodb.aws.credentials.type=static
quarkus.dynamodb.aws.credentials.access-key=test
quarkus.dynamodb.aws.credentials.secret-key=test

步骤3:编写测试类

import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.testcontainers.LocalStackContainer;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import jakarta.inject.Inject;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.testcontainers.containers.localstack.LocalStackContainer.Service.DYNAMODB;

@QuarkusTest
@QuarkusTestResource(value = LocalStackContainer.class, restrictToAnnotatedClass = true)
public class DynamoDBIntegrationTest {

    @Inject
    DynamoDbEnhancedClient enhancedClient;

    private static final String TEST_TABLE = "user-profiles";

    @BeforeEach
    void createTestTable() {
        // 假设你有对应的实体类UserProfile
        enhancedClient.table(TEST_TABLE, TableSchema.fromBean(UserProfile.class))
                .createTable();
    }

    @AfterEach
    void deleteTestTable() {
        enhancedClient.table(TEST_TABLE, TableSchema.fromBean(UserProfile.class))
                .deleteTable();
    }

    @Test
    void testDynamoDBOperations() {
        // 这里编写你的业务测试逻辑
    }
}

方案二:自定义QuarkusTestResourceLifecycleManager

如果需要完全自定义资源生命周期,可以手动构建客户端并读取配置,同时将配置传递给Quarkus应用。

自定义TestResource实现

import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;

import java.net.URI;
import java.util.Map;

public class DynamoDBTestResource implements QuarkusTestResourceLifecycleManager {

    private DynamoDbEnhancedClient enhancedClient;
    private static final String TEST_TABLE = "order-records";

    @Override
    public Map<String, String> start() {
        // 读取测试配置(也可从QuarkusConfigProvider获取)
        String localStackEndpoint = "http://localhost:4566";
        String region = "us-east-1";
        String accessKey = "test";
        String secretKey = "test";

        // 构建DynamoDB客户端
        DynamoDbClient client = DynamoDbClient.builder()
                .endpointOverride(URI.create(localStackEndpoint))
                .region(Region.of(region))
                .credentialsProvider(StaticCredentialsProvider.create(
                        AwsBasicCredentials.create(accessKey, secretKey)))
                .build();

        enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(client)
                .build();

        // 预创建测试表
        enhancedClient.table(TEST_TABLE, TableSchema.fromBean(OrderRecord.class))
                .createTable();

        // 将配置传递给Quarkus应用,确保应用内客户端使用同一配置
        return Map.of(
                "quarkus.dynamodb.endpoint-override", localStackEndpoint,
                "quarkus.dynamodb.aws.region", region,
                "quarkus.dynamodb.aws.credentials.access-key", accessKey,
                "quarkus.dynamodb.aws.credentials.secret-key", secretKey
        );
    }

    @Override
    public void stop() {
        if (enhancedClient != null) {
            // 清理测试表
            enhancedClient.table(TEST_TABLE, TableSchema.fromBean(OrderRecord.class))
                    .deleteTable();
            enhancedClient.close();
        }
    }
}

在测试类中使用自定义资源

import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;

@QuarkusTest
@QuarkusTestResource(DynamoDBTestResource.class)
public class DynamoDBManualTest {

    @Inject
    DynamoDbEnhancedClient enhancedClient;

    @Test
    void testCustomResourceSetup() {
        // 测试逻辑
    }
}

核心注意事项

  • QuarkusTestResourceLifecycleManager的初始化早于CDI容器,因此无法在其中使用CDI注入,必须手动构建客户端
  • LocalStack默认使用test/test作为访问凭证,测试环境配置必须与之匹配,否则会出现"table not found"或权限错误
  • 使用Testcontainers时无需硬编码LocalStack端口,通过环境变量引用即可避免端口冲突

内容的提问来源于stack exchange,提问作者Nicklas Karlsson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 01:32:18