如何模拟注入属性文件值的String值?

时间:2016-12-14 09:06:04

标签: java unit-testing dependency-injection mocking powermock

我的服务类中有这个成员:

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

在生产中使用类时,使用Spring从.properties文件注入的值。

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

@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之外,在测试中注入此值的最佳方法是什么?

3 个答案:

答案 0 :(得分:3)

使用Spring ReflectionTestUtils从Test class设置属性值。

ReflectionTestUtils.setField(targetObject, name, value);

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

  1. 将您的测试配置保留在src/test/resources
  2. 使用test utils(测试注释或环境抽象)在测试开始之前设置所需的属性
  3. 如果您正在进行非集成测试(没有弹簧),那么您必须自己完成。一种方法是使用反射(但它很糟糕)。另一方面,最好的方式,imho,是重构并始终通过构造函数而不是通过字段自动装配。这样在单元测试中,您可以在创建时明确配置对象:

    private final String region;
    
    @Autowired
    public MyClass(@Value("${dynamodb.aws.region}") String region) {
      this.region = region;
    }
    
    是的,它打字更多。但是你获得了不变性和非常容易的测试。此外,现在您可以将断言从init移动到构造函数。这可以为您提供更好的保护。没有人甚至可以创建不正确的对象,你不必记住在你的测试中调用init方法,也不知道spring是否肯定会调用它(可能是方法名称中有拼写错误) )