AmazonS3
がstaticなフィールドとして設定されている
- そのフィールドを呼ぶメソッドをテストしたい
のケースがあり、試行錯誤したのでメモ
- ケースバイケースだが、テスト元をリファクタリングをした方が良いケースもありそう
やったこと
AmazonS3
クラスでbucketを作成するメソッド
- テストコードは作成する場合、作成しない場合を両方テスト
- staticなフィールドを設定するためにリフレクションを使用した
サンプルコードと実行結果
サンプルコード
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.Bucket;
public class s3UseClass {
// 今ここのmock化を検証したいので、nullにしておく
private static AmazonS3 client = null;
public static boolean createBucket(String bucketName){
if (client.doesBucketExistV2(bucketName)) {
System.out.println("パターンfalse");
System.out.println("doesBucketExistV2");
System.out.println();
return false;
}
Bucket bucket = client.createBucket(bucketName);
System.out.println("パターンtrue");
System.out.println(bucket.toString());
System.out.println(client.getBucketLocation(bucketName));
System.out.println();
return true;
}
}
- テストコード
createBucketTrueTest
→ バケットが作成される場合のテスト
createBucketFalseTest
→ バケットが作成されない場合のテスト
initCreateBucketTest
でバケット作成される場合、されない場合の両方で使用する処理の用意
Bucket
、S3Client
のmockの用意
- テスト対象メソッドで呼び出すs3Clientのフィールドの用意
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.Bucket;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Field;
import static org.mockito.Mockito.*;
public class s3UseClassTest {
private String bucketName;
private String bucketLocation;
private AmazonS3 client;
private Bucket bucket;
@BeforeEach
void initCreateBucketTest() throws NoSuchFieldException, IllegalAccessException {
bucketName = "testBucketName";
bucketLocation = "testBucketLocation";
//mock化の宣言
client = mock(AmazonS3.class);
// bucketのmock宣言
bucket = mock(Bucket.class);
// field値の設定
// staticフィールド"client"を設定
// 設定用インスタンスの生成
s3UseClass testS3UseClass = new s3UseClass();
// フィールド値の設定
Field testClient = s3UseClass.class.getDeclaredField("client");
testClient.setAccessible(true);
testClient.set(testS3UseClass, client);
}
@Test
void createBucketTrueTest() throws NoSuchFieldException, IllegalAccessException {
// AmazonS3のmock定義
when(client.doesBucketExistV2(bucketName)).thenReturn(false);
when(client.createBucket(bucketName)).thenReturn(bucket);
when(client.getBucketLocation(bucketName)).thenReturn(bucketLocation);
// テスト対象メソッドを呼び出し
boolean checkResult = s3UseClass.createBucket(bucketName);
// ↑での定義したメソッドが呼ばれているか確認
verify(client, times(1)).doesBucketExistV2(bucketName);
verify(client, times(1)).createBucket(bucketName);
verify(client, times(1)).getBucketLocation(bucketName);
// 返り値がtrueであることを確認
Assertions.assertTrue(checkResult);
}
@Test
void createBucketFalseTest() throws NoSuchFieldException, IllegalAccessException {
// AmazonS3のmock定義
when(client.doesBucketExistV2(bucketName)).thenReturn(true);
// テスト対象メソッドを呼び出し
boolean checkResult = s3UseClass.createBucket(bucketName);
// ↑での定義したメソッドが呼ばれているかと、呼ばれていないことを確認
verify(client, times(1)).doesBucketExistV2(bucketName);
verify(client, times(0)).createBucket(bucketName);
verify(client, times(0)).getBucketLocation(bucketName);
// 返り値がFalseであることを確認
Assertions.assertFalse(checkResult);
}
}
実行結果
- 実行がTrueパターンとFalseパターンに分かれて出力されることを確認
- Trueパターンでは
- bucket情報が表示されること
- backetの場所がmockで指定した内容
- Falseパターンでは
doesBucketExistV2
と表示されること
- テストが2件passしていること
- カバレッジが100%
を確認
参考
コメント