2

我们有一个 spring 应用程序,它以几种方式之一运行,具体取决于特定属性,它必须是一小组值中的一个。当应用程序启动时,这个属性被传递给一个工厂,然后根据它构建稍微不同的 bean 实现。

我想为此控件的功能编写一个集成测试,以确保它在属性设置为各种值时工作;所以它需要运行一个属性设置为 1 的测试,一个属性设置为 2 的测试,等等。每个测试都需要根据需要设置属性,然后重新加载配置,以便正确重新配置所有内容。

在每个测试中获取上下文并手动刷新它似乎很简单,但是如何在运行时在测试中注入这些不同的属性来控制呢?有没有更好的方法来组织这种配置?

4

3 回答 3

1

我将回答你的第二个问题......那么,有没有更好的方法来组织这种配置?对于您的情况来说,这可能会让您不知所措,但是您是否看过 Spring Profiles?它可以满足您的需求,它是 Spring 3.1 中引入的新功能,因此 Spring 团队似乎选择了解决此类问题的方法。

这里有一个很棒的教程:http: //blog.springsource.org/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles/

于 2013-01-11T11:08:33.930 回答
1

我最终找到了一种直接执行此操作的方法。它有点混乱,但实际上并不算太糟糕。

最初,测试是使用@ContextConfiguration 运行的,然后new TestContextManager(getClass()).prepareTestInstance(this);在@Before 中进行初始化(单独初始化,因此我们可以使用Spring 之外的运行器)。

我将其扩展为首先注册一个文本执行侦听器,只要有一个可用的时候,它就会将 TestContext 抓取到测试本身中:

contextManager.registerTestExecutionListeners(new AbstractTestExecutionListener() {
    @Override
    public void prepareTestInstance(TestContext freshTestContext) throws Exception {
        testContext = freshTestContext;
    }
});

然后测试本身将一个属性注入到自定义的 PropertyPlaceholderConfigurer 中(非常简单:覆盖 resolvePlaceholder,调用 super.resolvePlaceholder,除非您之前明确设置了该属性),一旦它知道该属性的实际值是什么(不幸的是,直到实际测试) ,并调用:

testContext.markApplicationContextDirty();
contextManager.prepareTestInstance(this);

这使得 TestContext 重建应用程序上下文,现在使用新更改的属性值。

最后,您需要记住在测试之间重置属性,并可能将整个类标记为@DirtiesContext,以阻止它干扰您的其他测试。

于 2013-01-14T14:36:38.757 回答
0

考虑使用设置环境的 JVM 系统属性(例如“my.env=sit”),告诉配置器使用哪个属性文件。例如:

<context:property-placeholder   
    location="classpath:db-${my.env}.properties"/>

如果“my.env”属性设置为“sit”,那么 PropertyPlacementConfigurer 显然会寻找一个名为“db-sit.properties”的文件。

不要忘记设置ignoreUnresolvablePlaceholders为true。这将确保配置器在找不到属性时不会失败。

于 2013-01-11T11:15:45.067 回答