0

I have been trying to test my code which internally calls Amazons3.listObjects(), but i am struggling with mocking the Amazons3 class. Can some one please let me know the right way to do it?

here is the code Processor.class

 AmazonS3 s3 = getS3Build();

 final List<String> flagFiles = s3.listObjectsV2(dataBucket, flagFolder)


public AmazonS3 getS3Build() {
    return AmazonS3ClientBuilder.standard().withRegion(US_EAST_1).build();
  }

Test.class

Mockito.when(processor.getS3Build()).thenReturn(s3);

Mockito.when(s3.listObjectsV2(anyString(), anyString())).thenReturn(listObjectsV2Result);

Error occuring at s3.listObjectsV2

Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied;

I don't understand why its trying to call the actual listObjectsV2 when i have already mocked the class.

Thanks for the help :)

1 Answers1

1
Mockito.when(processor.getS3Build()).thenReturn(s3);

Mockito.when(s3.listObjectsV2(anyString(), anyString())).thenReturn(listObjectsV2Result);

At least the way you're showing it here the issue is that your test subject (processor) seems to be an already constructed Object. Setting the Amazon s3 member variable inline like that will cause that line of code to execute as soon as the Object is constructed.

So by the time you're mocking getS3Build it's already been called.

There are several different ways to reorganize your code to change this up to make it more testable:

  • you could make the Amazon s3 variable initialized after Object construction with an explicit initialize method
  • you could use Inversion of Control to inject the Amazon s3 variable into the Processor.class
  • you could use reflection or a explicit setter method to give you the flexibility to change the Amazon s3 member variable after Object construction

Helpful References

HackerMan0
  • 81
  • 1
  • 6