Home > Mobile >  Mock a method that returns a static variable
Mock a method that returns a static variable

Time:05-11

I am trying to mock the following line:

for (S3ObjectSummary objectSummary : S3Objects.withPrefix(s3, s3URI.getBucket(), s3URI.getKey())) {
     // some code
}

How do I go about mocking S3Objects.withPrefix? As per AWS documentation, the return type of this function is a static S3Objects (which is basically an iterable over a bucket).

I currently try to mock it using the following code:

@RunWith(PowerMockRunner.class)
@PrepareForTest({S3Objects.class})
public class TestMyMethod extends TestBase { 
      public void setup() {
            // setup other stuff and mock them
            PowerMockito.mockStatic(S3Objects.class);
            Mockito.when(S3Objects.withPrefix(any(), any(), any())).thenReturn(any(S3Objects.class));
            //continue setting up other stuff
}

CodePudding user response:

.thenReturn(any(S3Objects.class))  /* bad */

In Mockito syntax, including in PowerMockito, you can't use any in thenVerb or doVerb methods like thenReturn. any can only stand in for an argument during a when or verify call, and has other special rules specific to Mockito argument matchers. Mockito needs to know precisely which object you intend to return as part of thenReturn.

You'll need to create a mock(S3Objects.class) mock and make sure it returns a valid Iterator<S3ObjectSummary> when its iterator() method is called. I'd do this by creating a List<S3ObjectSummary> in your test and then delegate the iterator to it like this (untested code, but hopefully it works):

PowerMockito.mockStatic(S3Objects.class);
S3Objects mockS3Objects = mock(S3Objects.class);
List<S3ObjectSummary> objectsToReturn = new ArrayList<>();
objectsToReturn.add(/* ... */);

when(mockS3Objects.iterator())
    .thenAnswer((invocation) -> objectsToReturn.iterator());

when(S3Objects.withPrefix(any(), any(), any())).thenReturn(mockS3Objects);
  • Related