2

I have referred the answers to Mocking Objects Created Inside method Under test, How to mock objects created inside method? and other questions on net, but unable to understand why my solution is not working. My method to test is:

private AmazonS3 s3client;    
public int getBucketFileCount(String bucketNameForJsons) {
    if (s3client.doesBucketExistV2(bucketNameForJsons)) {
        log.info("Bucket name is not available.");
        return 0;
    }
    ObjectListing listing = s3client.listObjects(bucketNameForJsons);
    List<S3ObjectSummary> objectListing = listing.getObjectSummaries();
    log.info("Counting s3client files");
    return objectListing.size();
}

The test case I have written is:

@Mock
private AmazonS3 s3clientMock;
@Mock
private ObjectListing listingMock;
private final String SAMPLE_BUCKET = "SAMPLE_BUCKET";

@InjectMocks
private Accessor accessor;

@Test
public void testGetBucketFileCount() {
    s3clientMock = Mockito.mock(AmazonS3.class);
    listingMock = Mockito.mock(ObjectListing.class);
    //PowerMockito.when(s3clientMock.listObjects(anyString())).thenReturn(listingMock);
 //PowerMockito.doReturn(listingMock).when(s3clientMock).listObjects(anyString());
    //PowerMockito.when(s3clientMock.listObjects(Matchers.any(String.class))).thenReturn(listingMock);
    List<S3ObjectSummary> objectListing = new ArrayList<>();
    S3ObjectSummary objectSummary1 = Mockito.mock(S3ObjectSummary.class);
    S3ObjectSummary objectSummary2 = Mockito.mock(S3ObjectSummary.class);
    objectListing.add(objectSummary1);
    objectListing.add(objectSummary2);
    Mockito.doReturn(objectListing).when(listingMock).getObjectSummaries();
    int actualSize = accessor.getBucketFileCount(SAMPLE_BUCKET);
    //Assert.assertNotEquals(actualSize, EXPECTED_SIZE);
}

I have tried mocking ObjectListing listing = s3client.listObjects(bucketNameForJsons); in the following ways:

  • PowerMockito.when(s3clientMock.listObjects(anyString())).thenReturn(listingMock);

  • PowerMockito.doReturn(listingMock).when(s3clientMock).listObjects(anyString());

  • PowerMockito.when(s3clientMock.listObjects(Matchers.any(String.class))).thenReturn(listingMock);

However, the value I get for ObjectListing listing = s3client.listObjects(bucketNameForJsons) is still null.

How do I make it take listingMock value?

Thanks.

Tehreem
  • 476
  • 9
  • 23

1 Answers1

1

First of all, you are overcomplicating things, asy you are already using the annotation:

@Mock
private AmazonS3 s3clientMock;

You should stick to that then. Meaning: either use @RunWith or Mockito.initMocks. But you absolutely should not do s3clientMock = Mockito.mock(AmazonS3.class); again. (it doesn't hurt directly, but can lead to strange effects when you do it here, but do it different in another method)

Then: you don't need to use PowerMock(ito) here at all. You have two mocks, and you want to control and method call on each.

So a simple:

when(s3clientMock.listObjects(any())).thenReturn(listingMock);
when(listingMock.getObjectSummaries()).thenReturn(someList);

should do. someList would be a List<S3ObjectSummary>.

And then you could go:

assertThat(accessor.getBucketFileCount(SAMPLE_BUCKET), is(someList.size())

for example.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Yes, Thanks. So using plain Mockito (" Mockito.when(s3clientMock.listObjects(anyString())).thenReturn(listingMock);") worked, but with PowerMockito it does not, right? – Tehreem Nov 08 '18 at 10:21
  • 1
    No. I am saying: plain Mockito works. You should **only only only** use PowerMock(ito) if you absolutely have to. Meaning: you only need PowerMock(ito) for mocking new/static calls. And that is something that can be avoided by writing **easy** to test code. When you write your own code, and you think "I need PowerMockito for that", then you are doing something **wrong**. In other words: the default should be to only depend on the (latest) version of Mockito, and use nothing but that ;-) ... makes sense? – GhostCat Nov 08 '18 at 10:24