簡體   English   中英

將 stream 上傳到 Amazon S3 時如何單元測試異常?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM