Testcontainers の LocalStack を試してみる
はじめに
今回は、先日試した Testcontainers を活用して、LocalStack を使った AWS サービスのモックテストをやってみようと思います💪
具体的には、Amazon S3 のモック環境を構築し、実際の AWS 環境と同様の操作ができるテストコードの作成に取り組みます。
Testcontainers の LocalStack モジュール
Amazon S3 を操作するコード
まずは Amazon S3 を操作するコードを用意します。
今回は簡単のために以下のページをそのまま実装しました。
このサンプルコードのなかで今回は src/main/java/org/example/Handler.java
にある createBucket
メソッドを LocalStack を使ってテストしてみようと思います!
Testcontainers の LocalStack を使ったテストのサンプル
まずは pom.xml
に LocalStack モジュールを追加します。
以下の内容を加えてください。
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.20.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.20.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>localstack</artifactId>
<version>1.20.2</version>
<scope>test</scope>
</dependency>
次に src/test/java/org/example/HandlerTest.java
を書いていきます。
テストコードとしては単純に Handler.createBucket()
を実行して、バケットができたか確認しているだけです。
package org.example;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll;
import org.testcontainers.containers.localstack.LocalStackContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.services.s3.S3Client;
import org.testcontainers.utility.DockerImageName;
import java.net.URI;
import static org.junit.jupiter.api.Assertions.*;
@Testcontainers
class HandlerTest {
@Container
private static final LocalStackContainer localStack = new LocalStackContainer(
DockerImageName.parse("localstack/localstack:3.8"))
.withServices(LocalStackContainer.Service.S3);
private static S3Client s3Client;
@BeforeAll
public static void setUpAll() throws Exception {
s3Client = S3Client.builder()
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create(localStack.getAccessKey(), localStack.getSecretKey())))
.endpointOverride(URI.create(localStack.getEndpointOverride(LocalStackContainer.Service.S3).toString()))
.forcePathStyle(true)
.build();
}
@Test
void createBucket() {
Handler.createBucket(s3Client, "test-bucket");
// Check if the bucket exists
assertTrue(s3Client.listBuckets().buckets().stream().anyMatch(bucket -> bucket.name().equals("test-bucket")));
}
}
部分的に解説していきます。
@Container
private static final LocalStackContainer localStack = new LocalStackContainer(
DockerImageName.parse("localstack/localstack:3.8"))
.withServices(LocalStackContainer.Service.S3);
LocalStackContainer 型の静的フィールド localStack を定義しています。
LocalStackContainer は、LocalStack インスタンスを管理するための Testcontainers クラスです。
@Container アノテーションは、このコンテナが Testcontainers によって管理されることを表します。
LocalStackContainer は、特定の Docker イメージ localstack/localstack:3.8
で初期化されており、このイメージには LocalStack サービスが含まれています。
withServices メソッドは、S3 サービスがこの LocalStack インスタンスで利用可能であることを指定するために呼び出されます。
@BeforeAll
public static void setUpAll() throws Exception {
s3Client = S3Client.builder()
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create(localStack.getAccessKey(), localStack.getSecretKey())))
.endpointOverride(URI.create(localStack.getEndpointOverride(LocalStackContainer.Service.S3).toString()))
.forcePathStyle(true)
.build();
}
テストで使用される S3Clientをセットアップします。
メソッドは、AWS SDK for Java を使用して S3Client インスタンスを構築することから始まります。
S3Client.builder()
メソッドを呼び出してクライアントの設定を開始します。
credentialsProvider
メソッドは、クライアントの認証情報を設定するために使用されます。StaticCredentialsProvider.create
を使用して静的な AWS 認証情報を提供し、AwsBasicCredentials.create
を使用して認証情報を作成します。
アクセスキーとシークレットキーは、localStack コンテナから localStack.getAccessKey()
と localStack.getSecretKey()
を使用して取得できます。
次に、endpointOverride
メソッドを呼び出して S3 サービスのエンドポイントを設定します。
これは、LocalStack によって提供されるローカルの AWS サービスに対してテストを実行するために必要です。
エンドポイントは、localStack.getEndpointOverride(LocalStackContainer.Service.S3).toString()
を使用して取得され、ローカルの S3 サービスの URL を返します。
forcePathStyle(true)
メソッドは、S3 クライアントが LocalStack を使用する際に必要なパススタイルアクセスを使用するように設定します。
最後に、build() メソッドを呼び出して S3Client インスタンスを作成します。
このセットアップにより、S3Client が LocalStack によって提供されるローカルの S3 サービスと適切に連携できるようになり、実際の AWS クラウドにアクセスすることなくテストを実行することが可能になります。
テストの実行結果
リポジトリはこちら
最後に
TestcontainersとLocalStackを使用することで、AWS環境の構築やテストが効率化され、コスト削減にもつながります。
特にS3などのサービスを模擬環境で手軽にテストできるため、本番環境に依存せずに安全かつ迅速な開発・検証が可能です。ぜひ今回の手法を活用し、モックテストを実践してみてください!
Discussion