将JUnit运行器(Eclipse)的系统属性设置为测试Spring Web应用程序

23

我们的Web应用使用SystemPropertyPlaceholder根据系统属性的值加载属性文件(见下文)。

在本地运行时,缺省配置存储在application.properties中。对于生产服务器,我们目前只需在部署应用程序之前将"env"设置为"production",它将加载production.properties

现在要测试该应用程序,应使用test.properties文件。

如果我运行我们Jenkins构建中的所有测试,添加-Denv=test将按预期工作。但是,如果我只想使用集成JUnit运行器在Eclipse中运行某个单独的测试呢?

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = WebContextLoader.class, locations = {"classpath:application-context.xml" })
public class SomeTest {

有没有办法在Spring被加载之前告诉我的测试应该将系统属性“env”设置为“test”?因为使用MethodInvokingFactoryBean会在某些情况下仅在加载属性文件后才设置它:

<bean id="systemPrereqs"
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" value="#{@systemProperties}" />
    <property name="targetMethod" value="putAll" />
    <property name="arguments">
        <!-- The new Properties -->
        <util:properties>
            <prop key="env">test</prop>
        </util:properties>
    </property>
</bean>

<bean
    class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
    <property name="searchContextAttributes" value="true" />
    <property name="contextOverride" value="true" />
    <property name="ignoreResourceNotFound" value="true" />
    <property name="locations">
        <list>
            <value>classpath:application.properties</value>
            <value>classpath:${env}.properties</value>
            <value>${config}</value>
        </list>
    </property>
</bean>

<bean id="managerDataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="username">
        <value>${database.username}</value>
    </property>
    <property name="password">
        <value>${database.password}</value>
    </property>
    <property name="url">
        <value>${database.url}</value>
    </property>

</bean>

在应用程序属性文件application.properties、production.properties和test.properties中定义了数据库属性。

当然,关键是我希望在所有环境中使用相同的上下文文件,否则我可以告诉我的测试使用不同的上下文文件,在其中设置PropertyPlaceholder属性"location"为test.properties...但我也希望我的测试覆盖我的上下文,这样任何错误都可以尽早捕获(我正在使用spring-web-mvc对我们的 Web 应用程序进行端到端测试,它会加载整个 Web 应用程序并提供一些良好的反馈,我不想丢失这些)。

到目前为止,我唯一能想到的方法可能是配置JUnit运行器以包括一些系统属性设置参数,但我不知道如何做到这一点。


我建议在配置文件中使用profiles,导入你需要的正确文件。看起来你正在重新发明轮子。通过使用profile,你可以简单地在测试用例中添加@ActiveProfiles,以便加载正确的内容。然后你可以使用-Dspring.active.profiles=test代替-Denv=test - M. Deinum
3个回答

47

我正在解决完全相同的问题,希望已经找到了方法。你可以在测试用例的静态初始化器中调用System.setProperty()


3
当单独运行测试时,这样做是可行的,但在运行多个测试时可能并不一定适用,因为Spring上下文可能会在多个测试中被重用。 - pimlottc
@pimlottc,在我看来,在这种情况下运行多个测试不会造成任何问题。关键是我们必须在Spring上下文初始化之前设置系统属性。这可以通过使用静态初始化器来实现。如果所有共享相同Spring上下文的测试用例都设置了此属性(即为此情况),则Spring上下文将被正确初始化。 - AlexR
是的,我同意,如果静态初始化程序存在于共享上下文的每个测试类中,这可能在某些情况下不可行。 - pimlottc

20
在Eclipse中,右键单击JUnit测试类,选择“运行为>运行配置...”,然后转到“参数”选项卡,在VM参数下添加系统属性条目,例如 -Dcatalina.base=C:\programs\apache-tomcat-7.0.32。请保留原始html标签格式。

9
有没有一种默认的方法可以对所有测试执行此操作,这样您就不必为每个测试手动设置此属性? - Stewart

0
你可以尝试使用depends-on属性,让调用方法的bean在其他bean之前运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,