如何模拟注入属性文件值的字符串值?

How to mock String value of injected properties file value?

我得到了这个会员class:

@Value("${dynamodb.aws.region}")
private String region;

在生产环境中使用 class 时,使用我的 .properties 文件中的 Spring 注入的值。

然后,在测试模式下,我需要检查这段代码:

@Override
public void init() {
    if (StringUtils.isEmpty(region)){
        String msg = "Connection to DynamoDB couldn't be established. Region value is empty.";
        logger.error(msg);
        throw new IllegalArgumentException(msg);
    }
    this.dynamoDB = new DynamoDB(Regions.fromName(region));
}

除了使用 getter 和 setter 之外,在测试中注入此值的最佳方法是什么?

您也可以在 src/test/resources 中添加一个 application.properties(或 .yml)。在那里你可以定义你想要 Spring 在测试阶段注入的值。

使用 Spring ReflectionTestUtils 设置来自测试 class 的 属性 值。

ReflectionTestUtils.setField(targetObject, name, value);

Link to Javadoc

如果您正在进行集成测试,那么 spring 至少为您提供两种方法:

  1. src/test/resources
  2. 中保留您的测试配置
  3. 使用测试实用程序(测试注释或环境抽象)在测试开始前设置所需的属性

如果您正在进行非集成测试(没有 spring),那么您必须自己进行。一种方法是使用反射(但很糟糕)。换句话说,恕我直言,最好的方法是重构并始终通过构造函数而不是通过字段自动装配。这样在单元测试中你可以在创建时显式配置你的对象:

private final String region;

@Autowired
public MyClass(@Value("${dynamodb.aws.region}") String region) {
  this.region = region;
}

是的,更多的是打字。但是你会得到不变性和非常容易的测试。此外,现在您可以将断言从 init 移至构造函数。这为您提供了更好的保护。没有人甚至能够创建不正确的对象,您不必记住在测试中调用 init 方法,也不必想知道 spring 是否肯定会调用它(也许在方法名称)