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);