@Resource dataSource mappedName - 覆盖以在非JNDI环境中测试

时间:2012-06-13 09:05:16

标签: spring unit-testing jndi spring-test

我有一个我们在Jboss中部署的现有服务bean。不幸的是,它的dataSource引用被配置为通过JNDI服务的“mappedName”查找注入数据源引用。

@Resource(name = "dataSource", mappedName = "java:/OracleDS")
private DataSource dataSource = null;

我想在非JNDI环境中测试bean。当我在非JNDI环境中运行时,我期望得到这个异常。

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating 
bean with name 'myService': Injection of resource fields failed; nested exception 
is org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean 
definition with name 'java:/OracleDS' defined in JNDI environment: JNDI lookup 
failed; nested exception is javax.naming.NoInitialContextException: Need to 
specify class name in environment or system property, or as an applet parameter, 
or in an application resource file:  java.naming.factory.initial

我意识到解决这个问题的最快方法是删除mappedName限制,因为生产或测试spring上下文可以定义数据源。但在我无法做到这一点的情况下。有没有办法通过测试弹簧上下文定义InitialContext以避免上面的异常。

1 个答案:

答案 0 :(得分:0)

我在SimpleNamingContextBuilder上做了一些阅读,并为我的测试用例提供了这个上下文设置。诀窍是使用MethodInvokingFactoryBean来确保调用bind()方法。

<bean id="jndiContext" class="org.springframework.mock.jndi.SimpleNamingContextBuilder" factory-method="emptyActivatedContextBuilder"/>

<bean id="invokingFactoryBean"
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject">
        <ref local="jndiContext" />
    </property>
    <property name="targetMethod">
        <value>bind</value>
    </property>
    <property name="arguments">
        <list>
            <value>java:/OracleDS</value>
            <ref bean="dataSource" />
        </list>
    </property>
</bean>

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