Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I unit test the getObject method of the AWS S3 SDK using Java?

Tags:

I'm working with Java and I'm using the AWS SDK for interact with S3. I've the following method and I want to unit test it

private final S3Client s3Client;
...
...
public byte[] download(String key) throws IOException {
    GetObjectRequest getObjectRequest = GetObjectRequest.builder()
            .bucket("myBucket")
            .key(key)
            .build();
    return s3Client.getObject(getObjectRequest).readAllBytes();
}

For this purpose I'm using JUnit 5 and Mockito. The problem is that I don't know how to mock the result of

s3Client.getObject(getObjectRequest) 

because the return type

ResponseInputStream<GetObjectResponse> 

is a final class.

Any idea or suggestions? Thank you

like image 413
Gavi Avatar asked Nov 28 '19 19:11

Gavi


2 Answers

In case anyone is still looking for a different solution this is how I did it:
This is the code that needs to be mocked:

InputStream objectStream =
    this.s3Client.getObject(
        GetObjectRequest.builder().bucket(bucket).key(key).build(),
        ResponseTransformer.toInputStream());

This is how to mock it:

S3Client s3Client = Mockito.mock(S3Client.class);
String bucket = "bucket";
String key = "key";
InputStream objectStream = getFakeInputStream();
when(s3Client.getObject(
        Mockito.any(GetObjectRequest.class),
        ArgumentMatchers
            .<ResponseTransformer<GetObjectResponse, ResponseInputStream<GetObjectResponse>>>
                any()))
    .then(
        invocation -> {
          GetObjectRequest getObjectRequest = invocation.getArgument(0);
          assertEquals(bucket, getObjectRequest.bucket());
          assertEquals(key, getObjectRequest.key());

          return new ResponseInputStream<>(
              GetObjectResponse.builder().build(), AbortableInputStream.create(objectStream));
        });
like image 67
iulian16 Avatar answered Sep 28 '22 19:09

iulian16


The problem is solved. In a maven project you can add a file named "org.mockito.plugins.MockMaker" in the folder "src/test/resources/mockito-extensions".

Inside the file, add "mock-maker-inline" without quotes.

From now Mockito will be able to mock final classes also.

like image 23
Gavi Avatar answered Sep 28 '22 20:09

Gavi