如何控制在测试环境和生产环境之间变化的弹簧注射?

时间:2012-10-26 19:40:26

标签: spring maven struts2 continuous-integration integration-testing

我正在设置一个CI情境,我将把我的Web应用程序部署到测试环境中。在这个测试环境中,我希望应用程序使用的业务对象是真实的;模拟将返回静态测试数据。我正在使用它来再次运行我的ui测试。我正在控制使用Spring注入这些业务对象依赖项;这是一个struts 2应用程序,这是值得的。

我认为我的问题与Maven有关。让我的Maven构建决定是否构建弹簧配置以注入模拟或注入真实物体的最佳方法是什么?这对maven配置文件有用吗?其他选择?

2 个答案:

答案 0 :(得分:3)

Spring本身支持profiles(如果您使用的是3.1或更新版本),对于Web应用程序,您可以使用context-parameter为 Web中的不同环境设置活动配置文件。 XML

<context-param>
   <param-name>spring.profiles.default</param-name>
   <param-value>test</param-value>
</context-param>

编辑:对于Maven&amp; Jenkins,您应该能够为构建作业设置参数,如下所示:

首先,让Maven过滤您的xml资源(在此示例中,只过滤了以xml结尾的文件,其他文件包含在内而不进行过滤),方法是将以下内容添加到 pom.xml <build> </build> -tags:

    <resources>
        <resource>
            <directory>src/main/webapp</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/webapp</directory>
            <filtering>false</filtering>
            <excludes>
                <exclude>**/*xml</exclude>
            </excludes>
        </resource>
    </resources> 

然后,参数化 web.xml 中的context-param:

<context-param>
   <param-name>spring.profiles.default</param-name>
   <param-value>${env.SPRINGPROFILE}</param-value>
</context-param>

然后参数化Jenkins中的构建作业,为SPRINGPROFILE设置所需的字符串参数(例如 test prod ):https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+Build

答案 1 :(得分:1)

使用构建Web应用程序工件(Maven best practice for generating artifacts for multiple environments [prod, test, dev] with CI/Hudson support?)做任何事情都可能是个坏主意。虽然您可以使用各种机制来生成具有针对不同上下文的Spring注入的不同配置的WAR文件,但WAR构件在每次构建时应该是相同的。

为了从WAR中提取配置,我使用Spring 3的功能从外部属性文件中提取覆盖值。我定义了业务对象的默认值,即生产价值。我配置spring来检查是否存在属性文件,当应用程序处于测试环境并需要模拟注入时,我将部署该文件。如果该属性文件存在,则会注入其值。这是spring配置文件的相关部分。

<!-- These are the default values -->
    <util:properties id="defaultBeanClasses">
    <prop key="myManagerA">com.myco.ManagerAImpl</prop>
    <prop key="myManagerB">com.myco.ManagerBImpl</prop>
</util:properties>

<!-- Pull in the mock overrides if they exist. -->
<context:property-placeholder 
    location="file:///my/location/mockBeans.properties"
    ignore-resource-not-found="true"
    properties-ref="defaultBeanClasses"/>

<!-- The beans themselves. -->  
<bean id="managerA" class="${myManagerA}"/>
<bean id="managerB" class="${myManagerB}"/>

以下是外部“mockBeans.properties”文件的内容:

#Define mock implementations for core managers
myManagerA=com.myco.ManagerAMockImpl
myManagerB=com.myco.ManagerBMockImpl

这很好用。如果愿意,您甚至可以在实际WAR中包含mockBeans.properties文件,但不能在实时位置中包含。然后测试环境任务也会将它移动到spring配置指向的位置。或者,您可以将模拟属性驻留在完全不同的项目中。