模拟一个 returns 静态变量的方法

Mock a method that returns a static variable

我正在尝试模拟以下行:

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

如何模拟 S3Objects.withPrefix?根据 AWS 文档,此函数的 return 类型是静态 S3Objects(基本上是一个存储桶上的可迭代对象)。

我目前尝试使用以下代码模拟它:

@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
}
.thenReturn(any(S3Objects.class))  /* bad */

在 Mockito 语法中,包括在 PowerMockito 中,您不能在 thenVerbdoVerb 方法中使用 any,例如 thenReturnany 只能在 whenverify 调用期间代表参数,并且有 other special rules specific to Mockito argument matchers。 Mockito 需要准确地知道您打算 return 作为 thenReturn.

的一部分的对象

您需要创建一个 mock(S3Objects.class) 模拟,并确保它 return 在其 iterator() 方法被调用时是一个有效的 Iterator<S3ObjectSummary>。我会通过在你的测试中创建一个 List<S3ObjectSummary> 然后将 iterator 委托给它来做到这一点(未经测试的代码,但希望它有效):

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