原创

Testcontainer および LocalStack との統合テスト

温馨提示:
本文最后更新于 2024年04月12日,已超过 37 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

新しいユーザーを AWS Cognito (ユーザープール) に伝播する AuthService の統合テストを作成しようとしています

@Service
@RequiredArgsConstructor
public class AuthService {

    /**
     * The algorithm used for HMAC-SHA256 hashing.
     */
    private static final String HMAC_SHA256_ALGORITHM = "HmacSHA256";

    /**
     * The client for interacting with Amazon Cognito Identity Provider.
     */
    private final CognitoIdentityProviderClient client;

    /**
     * The AWS properties containing necessary configuration.
     */
    private final AwsProperties properties;

    /**
     * Signs up a user using the provided SignUpDto.
     *
     * @param requestDto The SignUpDto containing user signup information.
     */
    public void signUp(SignUpDto requestDto) {
        final AttributeType attributeType = AttributeType.builder()
                .name("email")
                .value(requestDto.email())
                .build();

        final String secretVal = calculateSecretHash(properties.getClientId(),
                properties.getSecretKey(),
                requestDto.email());
        final SignUpRequest request = SignUpRequest.builder()
                .userAttributes(List.of(attributeType))
                .username(requestDto.email())
                .password(requestDto.password())
                .clientId(properties.getClientId())
                .secretHash(secretVal)
                .build();

        client.signUp(request);
    }

    /**
     * Confirms user signup using the provided UserConfirmationDto.
     *
     * @param confirmation The UserConfirmationDto containing user confirmation information.
     */
    public void confirmSignUp(UserConfirmationDto confirmation) {
        final ConfirmSignUpRequest req;
        req = ConfirmSignUpRequest.builder()
                .clientId(properties.getClientId())
                .confirmationCode(confirmation.confirmationCode())
                .username(confirmation.email())
                .secretHash(calculateSecretHash(properties.getClientId(),
                        properties.getSecretKey(),
                        confirmation.email()))
                .build();


        client.confirmSignUp(req);
    }

    /**
     * Calculates the secret hash for the provided user pool client ID, client secret, and email.
     *
     * @param userPoolClientId     The user pool client ID.
     * @param userPoolClientSecret The user pool client secret.
     * @param email                The user's email.
     * @return The calculated secret hash.
     * @throws SecretHashException If an error occurs during secret hash calculation.
     */
    private String calculateSecretHash(String userPoolClientId, String userPoolClientSecret, String email) {
        final SecretKeySpec signingKey = new SecretKeySpec(
                userPoolClientSecret.getBytes(StandardCharsets.UTF_8),
                HMAC_SHA256_ALGORITHM);

        final Mac mac;
        try {
            mac = Mac.getInstance(HMAC_SHA256_ALGORITHM);
            mac.init(signingKey);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new SecretHashException(e.getMessage());
        }

        mac.update(email.getBytes(StandardCharsets.UTF_8));
        final byte[] rawHmac = mac.doFinal(userPoolClientId.getBytes(StandardCharsets.UTF_8));
        return java.util.Base64.getEncoder().encodeToString(rawHmac);
    }
}

これが私のbuild.gradleです

plugins {
    id 'java'
    id 'checkstyle'
    alias(libs.plugins.spring.boot)
    alias(libs.plugins.dependency.management)
}

group = 'java.com.mykytaaa'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation(libs.spring.starter.weblux)
    compileOnly(libs.lombok)
    annotationProcessor(libs.lombok)
    testImplementation(libs.spring.starter.test)
    testImplementation(libs.reactor)
    implementation(libs.mapstruct)
    annotationProcessor(libs.mapstruct.processor)

    testImplementation 'org.testcontainers:localstack:1.19.7'
    testImplementation 'org.testcontainers:junit-jupiter:1.19.7'

    testCompileOnly 'org.projectlombok:lombok:1.18.30'
    testAnnotationProcessor 'org.projectlombok:lombok:1.18.30'


    runtimeOnly(libs.awssdk.bom)
    implementation(libs.awssdk.cognitoidentityprovider)
}

tasks.named('test') {
    useJUnitPlatform()
}

何をしたらよいのか、どのように設定すればよいのか教えていただけますか?

これが私の現在の構成ですが、機能がなく、正しいアプローチであるかどうかはわかりません。

@SpringBootTest
@ActiveProfiles("test")
public abstract class AbstractIntegrationTestBase {

    public static LocalStackContainer localStack = new LocalStackContainer(DockerImageName.parse("localstack/localstack"));

    @BeforeAll
    static void runContainer() {
        localStack.start();
    }

}
@Configuration
public class AwsConfiguration {

    /**
     * Creates and configures an instance of CognitoIdentityProviderClient.
     *
     * @param region The AWS region used for configuration.
     * @return An instance of CognitoIdentityProviderClient.
     */
    @Bean
    public CognitoIdentityProviderClient identityProviderClient(@Value("${aws.region}") Region region) {
        return CognitoIdentityProviderClient.builder()
                .endpointOverride(AbstractIntegrationTestBase.localStack.getEndpoint())
                .region(region)
                .build();
    }
}
@RequiredArgsConstructor
@ExtendWith(SoftAssertionsExtension.class)
public class AuthServiceIntegrationTest extends AbstractIntegrationTestBase {

    private final AuthService authService;

    @Test
    void shouldSuccessfullySignUpUser(SoftAssertions softly) {
        final SignUpDto signUpDto = new SignUpDto(
                "[email protected]",
                "qQ-123456789"
        );

        authService.signUp(signUpDto);
    }
}
正文到此结束
热门推荐
本文目录