在Grails中测试不同的resources.xml?

时间:2015-11-20 13:37:35

标签: grails testing

我在resources.xml文件夹下有grailsApp/conf/spring并且所有bean都已初始化,但我希望测试Vs的实际上有不同的bean定义。

我是否可以单独test-resources.xml并在测试期间加载它,而在加载resources.xml时会加载它?

1 个答案:

答案 0 :(得分:2)

您是否仅限于使用XML进行bean定义?使用resources.groovy是首选方法,因为它提供了强大的DSL,根据环境定义bean很简单:

import grails.util.Environment

beans = {
    switch(Environment.current) {
        case Environment.TEST:
            myBean(String, "test string")
            break

        case Environment.DEVELOPMENT:
            myBean(String, "dev string")
            break
    }
}

您可以在Grails and Spring上的文档中查看更多示例。

选项2

如果您无法使用Grails Spring DSL进行bean定义,则可以使用某种混合方法。将resources.xml移出conf/spring/以及类路径上的其他位置。在它旁边,创建另一个XML文件,该文件包含测试环境的bean定义,我们称之为resources-test.xml。然后使用以下内容将resources.groovy文件添加到conf/spring/

import grails.util.Environment

beans = {

    switch(Environment.current) {
        case Environment.TEST:
            importBeans('classpath:/resources-test.xml')
            break

        case Environment.DEVELOPMENT:
            importBeans('classpath:/resources.xml')
            break
    }

}

此方法允许您将bean定义保留为XML,但使用Grails Spring DSL来打开环境。

选项3

根据您在resources.xml中处理的bean的复杂性和数量,也许您可​​以使用BeanFactoryPostProcessor。 Spring的BeanFactoryPostProcessor允许您在初始化之前挂钩bean,以便您可以修改它们的定义。您需要在src/groovy中创建一个实现BeanFactoryPostProcessor的类,如下所示:

import grails.util.Environment
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory
import org.springframework.beans.BeansException
import org.springframework.beans.factory.config.ConstructorArgumentValues

class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        if (Environment.current == Environment.TEST) {
            BeanDefinition definition = beanFactory.getBeanDefinition('myBean')
            ConstructorArgumentValues constructorArgs = definition.constructorArgumentValues
            constructorArgs.clear()
            constructorArgs.addGenericArgumentValue("Modified for test")
        }
    }
}

然后在resources.xml中注册:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    <bean id="myBean" class="java.lang.String">
        <constructor-arg value="this will be overwritten" />
    </bean>

    <bean id="postProcessor" class="CustomBeanFactoryPostProcessor" />
</beans>

这显然是一个非常简单的示例,但在运行测试时,myBean值将设置为"Modified for test"而不是"this will be overwritten"

选项4

为每个环境单独定义bean的替代方法是通过添加doWithSpring闭包覆盖测试类本身内部的bean:

static doWithSpring = {
    myBean(String, 'Modified for test')
}

void "test bean is overridden"() {
    expect:
    grailsApplication.mainContext.getBean('myBean') == 'Modified for test'
}