为什么模拟对象 return 的 getter() 为空?

Why does the getter() of mock object return null?

我有一个 class ResolverChainContext:

public class ResolverChainContext {
  private AWSCredentialsProvider assumeRoleCredentials;
}

并且在 setup() 单元测试中(Groovy 和 Spock),我用 Mock:

填充上面的字段
def setup() {
  def ctx = ResolverChainContext.builder().build()

  ctx.setAssumeRoleCredentials(Mock(AWSCredentialsProvider.class))
}

接下来在我的测试用例中,我调用了一个方法 getDynamoDBCredentialsV2(),我想从 getDynamoDBCredentials() 中获取 v1Credentials,而 getDynamoDBCredentials() 来自 setup() 步骤中的 Mock 对象:


public interface AWSCredentialsProvider {
    AWSCredentials getCredentials();

    void refresh();
}

protected AWSCredentialsProvider getDynamoDBCredentials() {
    final AWSCredentialsProvider fasCredentials = resolverChainContext.getFasCredentials();
    final AWSCredentialsProvider roleCredentials = resolverChainContext.getAssumeRoleCredentials();
    if (null == fasCredentials || !invokerConfig.isUseCallerCredentials()) {
        return roleCredentials;
    } else {
        return fasCredentials;
    }
}

protected AwsCredentialsProvider getDynamoDBCredentialsV2() {

    AWSCredentials v1Credentials = getDynamoDBCredentials().getCredentials();

    blahblahblah;
}

问题是我会得到 null for v1Credentials.

我调试的时候,roleCredentials的类型是"Mock for type AWSCredentialsProvider"。在调用 getCredentials() 之后,它得到 null.

是不是我用错了Groovy?我怎样才能使 v1Credentials 成为它应该成为的对象?我应该使用 Mock/Stub 吗?

它 returns 为空,因为 AWSCredentialsProvider#getCredentials 的行为未定义。

从 Spock 的 interaction based testing 的文档中,当未在模拟对象方法上定义行为时,将返回其默认值,在您的情况下 Object 的默认值为 null

Initially, mock objects have no behavior. Calling methods on them is allowed but has no effect other than returning the default value for the method’s return type (false, 0, or null). An exception are the Object.equals, Object.hashCode, and Object.toString methods

为了克服这个问题,您可能需要使用 stubbing as explained in the doc.

定义 AWSCredentialsProvider#getCredentials 方法调用的行为