ReflectionTestUtils.setfield 未覆盖本地项目 属性 属性

ReflectionTestUtils.setfield is not overriding the local project property attribute

我正在努力解决如何覆盖 .yml 文件中的 属性 文件

我们使用 Spring 框架并使用注释(例如@InjectMocks)。

我在名为 "one-platform-properties" 的配置项目 YML 文件中声明了一个名为 paysafe-ss-fx-service.yml 的属性。它设置了一个名为 maxRecoveryAge=0 的变量。这本质上是一个时间缓冲。

  oneplatform:
  environment: local
publisher:
  rates:
    maxRecoveryAge: 0
    interPublishDelay: 500

问题是我希望能够在我的测试中 运行 时调整它。将缓冲区设置为 1 小时、5 小时和 24 小时。

我在测试中使用 ReflectionTestUtils.setfield(PublisherClass, "maxDocumentAge", 1, int.class) 调用来调整时间,但该值未被覆盖。当我观察它在我的测试工具中工作的变量时,但是一旦测试 运行 渗透到微服务代码中,覆盖的值就会丢失。关于如何在所有测试中保持覆盖值的任何想法?

我的目标是在我的测试中使用不同的变体 运行:

ReflectionTestUtils.setField(new FxRatesEventPublisher(),"maxRecoveryAge",1,int.class);
ReflectionTestUtils.setField(new FxRatesEventPublisher(),"maxRecoveryAge",5,int.class);
ReflectionTestUtils.setField(new FxRatesEventPublisher(),"maxRecoveryAge",24,int.class);

并基本上覆盖项目定义的属性文件中定义的值。

为什么不使用 @TestPropertySource#properties

The following example demonstrates how to declare inlined properties.

@ContextConfiguration
@TestPropertySource(properties = { "timezone = GMT", "port: 4242" })
public class MyIntegrationTests {
    // class body...
}

请注意 javadocs:

@TestPropertySource is a class-level annotation

这意味着您需要为要使用的不同配置值设置不同的 类。

ReflectionTestUtils.setField(producerConfiguration, "messageProducer", realProducer);
Object target = AopTestUtils.getUltimateTargetObject(fxRatesEventPublisher);
int recoveryAge = -1;
ReflectionTestUtils.setField(target, "maxRecoveryAge", recoveryAge);

我假设您没有遵循告诉我们 prefer constructor based injection over field based injection 的最新 Spring 惯例和最佳实践。

如果你的 bean 是这样声明的:

public class FxRatesEventPublisher {
    private final Integer maxRecoveryAge;
    private final SomeDependency someDependency;

    public FxRatesEventPublisher(@Value("${publisher.rate.maxRecoveryAge}") Integer maxRecoveryAge, @Autowired SomeDependency someDependency) {
        this.maxRecoveryAge = maxRecoveryAge;
        this.someDependency = someDependency;
    }
}

然后你可以像这样实例化它:

// Create an instance with your test values injected. Note that you could inject mocked dependency here as well as the real one.
FxRatesEventPublisher fxRatesEventPublisher = new FxRatesEventPublisher(24, mockDependency); 

在这种情况下,测试组件要容易得多,因为您可以将任何值传递给构造函数。我同意这似乎不如基于 属性 的注入漂亮,但至少值得一看。