はじめに
サーバサイドkotlinでAmazonS3にファイルを登録する実装をしています。
今回、テストコードでS3登録をローカル環境で動かすためにLocalStackのJUnit統合をやってみました。
モックライブラリにはMockKを使用しています。
LocalStack / Integration with Java/JUnit
https://github.com/localstack/localstack#integration-with-javajunit
MockK
https://github.com/mockk/mockk
LocalStackの導入と起動
$ pip install localstack
$ localstack start
gradle
Envとかは省略してます
testCompile group: 'cloud.localstack', name: 'localstack-utils', version: '0.2.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.1'
testImplementation "org.junit.jupiter:junit-jupiter-api:5.5.1"
testImplementation("by.dev.madhead.aws-junit5:s3-v1:5.0.4")
testImplementation("by.dev.madhead.aws-junit5:s3-v2:5.0.4")
testImplementation("io.mockk:mockk:1.9.3")
本文
LocalStackのモック用S3Client生成クラス
object LocalStackS3Client {
fun makeS3Client(): AmazonS3 {
val client = TestUtils.getClientS3() // LocalStackによるS3Client生成
val bucketName = UUID.randomUUID().toString() // なんでもよい
client.createBucket(bucketName)
return client
}
}
本物のS3Client生成クラス
object AmazonS3Client {
@JvmStatic
fun makeS3Client(): AmazonS3 {
//aws-java-sdk-s3を用いた本物の処理。中身は省略。
return client
}
}
テストクラス
@ExtendWith(LocalstackDockerExtension::class)
@LocalstackDockerProperties(services = ["s3"], randomizePorts = true)
class AmazonS3UploadTest {
@Test
fun testAmazonS3Upload() {
// File作成のprivateメソッド、省略
val file = createFile()
// モック用S3Clientを呼び出すように設定
mockkStatic(AmazonS3Client::class)
every { AmazonS3Client.makeS3Client() } return LocalStackS3Client.makeS3Client()
// モック用S3Clientが生成される
val client = AmazonS3Client.makeS3Client()
// S3にファイルを送信
try {
client.putObject(PutObjectRequest(Env.BUCKET_NAME, file.name, file)
} catch (e: AmazonClientException) {
throw e
}
// テストクラスを終わらせるための手抜き
assertThat("hoge").isEqualTo("hoge")
}
まとめ
LocalStack+JUnitを使えば、シンプルな記述でawsのローカル環境でのテストができて良いですね!
今回はS3を使いましたが、DynamoDBやSQSなど他のサービスでも同じようなことが可能ですので、
詳しくは知りたい方は↑のgithubのReadmeをご覧ください。
間違ってるところがあるかもしれないので、
時間があれば手抜きしてるところと共に書き直します。