[英]How to unit test exception when uploading stream to Amazon S3?
我有以下代碼將 json 上傳到 s3
private final S3Client s3Client;
private final String bucketName;
public S3ClientWrapper(final Config s3Config) {
final String region = s3Config.getString(REGION_CONFIG_NAME);
bucketName = s3Config.getString(BUCKET_NAME);
final S3ClientBuilder s3ClientBuilder = S3Client.builder();
s3ClientBuilder.region(Region.of(region));
s3Client = s3ClientBuilder.build();
}
public boolean sendEvents(List<Obj> events) {
String key = getKey();
PutObjectRequest objectRequest = PutObjectRequest.builder()
.bucket(bucketName)
.key(key)
.build();
try {
s3Client.putObject(objectRequest, RequestBody.fromContentProvider(() -> {
PipedOutputStream outputStream = new PipedOutputStream();
GZIPOutputStream gzipOutputStream = null;
try {
gzipOutputStream = new GZIPOutputStream(outputStream);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
GZIPOutputStream finalGzipOutputStream = gzipOutputStream;
events.stream().map(Json::writeValueAsString)
.map(json -> json + "\n")
.forEach(json -> {
try {
finalGzipOutputStream.write(json.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
try {
return new PipedInputStream(outputStream);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}, "application/octet-stream"));
return true;
}catch (S3Exception e) {
log.error("failed to send raw data events to S3", e);
return false;
}
}
我想對無法上傳到 S3 並引發 S3Exception 的情況進行單元測試。 我如何編寫單元測試來測試我的 function 中的這種情況?
我在這里使用 Mockito,但在其他庫的情況下,機制會類似。 我們需要創建模擬的s3Client
並將其注入到測試的 class 中。在調用測試的方法之前,我們必須聲明模擬的預期行為,在本例中將拋出S3Exception
。
由於使用了 static S3Client.builder()
方法,我們需要使用mockStatic
方法來模擬客戶端創建,我們需要mockito-inline
來做到這一點(我將鏈接下面的文檔參考)。
@Test
void s3ExceptionThrown() {
try (var mocked = Mockito.mockStatic(S3Client.class)) {
// creation of the two mock objects below can be moved before the try
var builder = mock(S3ClientBuilder.class);
var s3Client = mock(S3Client.class);
// to mock a static method we have to use `when` method from the object created by `mockStatic`
mocked.when(S3Client::builder).thenReturn(builder);
// here we mock non-static methods, so standard `Mockito.mock` method can be used
when(builder.build()).thenReturn(s3Client);
when(s3Client.putObject(any(), any(), any()).thenThrow(new S3Exception());
var testedWrapper = new S3ClientWrapper(/* config */);
var result = testedWrapper.sendEvents(null); // param irrelevant for this test
assertFalse(result);
}
}
(重要說明:代碼是用手機記事本寫的,所以可能編譯不好,但機制已經顯示出來,作為一個概念應該可以正常工作)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.