java - Spring 单元测试和 InitialContext

标签 java spring unit-testing spring-mvc tomcat

我想在运行 Tomcat 和 Spring 4 的情况下进行简单的集成测试,注入(inject)一个 spring 组件并使用我现有的 Tomcat 数据源配置。我不想两次配置我的数据源。 所有内容,包括我的数据源,都在文件 WebContent/WEB-INF/application-context.xml 中配置。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task"
    xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
                http://www.springframework.org/schema/data/jpa      http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
        http://www.springframework.org/schema/jee           http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">

    <task:annotation-driven />

    <!-- annotations in bean classes -->
    <!-- context:annotation-config / -->

    <!-- mvc:annotation-driven / -->
    <context:component-scan base-package="com.mycompany.package.**" />

    <jpa:repositories base-package="com.mycompany.package.**" />


    <!-- <aop:aspectj-autoproxy proxy-target-class="true"/> -->

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
        <property name="jpaDialect" ref="jpaDialect" />
    </bean>

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="persistenceUnitName" value="packagePU" />
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
        </property>
        <property name="jpaPropertyMap">
            <props>
                <prop key="eclipselink.weaving">false</prop>
            </props>
        </property>
    </bean>

    <bean id="jpaVendorAdapter"
        class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
        <property name="generateDdl" value="false" />
        <property name="showSql" value="true" />
    </bean>

    <bean id="jpaDialect"
        class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
    <!-- <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> 
        <property name="validationMessageSource" ref="messageSource"/> </bean> -->

    <bean id="messageSource"
        class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basenames" value="i18n/messages" />
    </bean>

    <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/DefaultDB" />

</beans>

我正在使用本教程 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html#testcontext-ctx-management ,但我不完全理解如何在提供我的数据源的 Tomcat 上下文中运行我的测试。

目前,我是这样的:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = { "file:WebContent/WEB-INF/application-context.xml"})
public class SimulatorTest {

    @Autowired
    private ShiftSimulator simulator;

    @BeforeClass
    public void setup() {
        // ??? 

    }


    @Test
    public void testShiftStart() {
        System.out.println("Hello world");
    }

}

目前,我在运行测试时遇到这个错误

java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in URL [file:WebContent/WEB-INF/application-context.xml]: Cannot resolve reference to bean 'dataSource' while setting bean property 'dataSource'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Invocation of init method 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
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Invocation of init method 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
...
Caused by: 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
...

我完全理解需要有一个 InitialContext,但是我如何为我的测试提供 Tomcat 提供的上下文,包括我的数据源配置?我不想两次设置我的数据源连接凭据。

最佳答案

解决了。简单回顾一下问题:Spring 尝试创建 dataSource bean,但在查找 JNDI 名称时失败了——因为没有可用的 JNDI。

所以我为测试做了什么,我只是创建了另一个覆盖 bean dataSource 的 XML 文件。我在版本控制中忽略了该文件,并要求每个开发人员将此文件复制到位:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        p:driverClassName="com.sap.db.jdbc.Driver"
        p:url="jdbc:sap://xxx:30015"
        p:username="sa"
        p:password="">
    </bean>

</beans>

在测试类中,我提供了覆盖 dataSource 的附加文件引用,因此它永远不会尝试执行失败的 JNDI 查找:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = { "file:WebContent/WEB-INF/application-context.xml", "file:WebContent/WEB-INF/test-datasource.xml"  })
public class SimulatorTest {
...

关于java - Spring 单元测试和 InitialContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34800498/

相关文章:

asp.net - 如何在 ASP.net 核心单元测试项目中模拟 session 变量?

java - 实现同步以获得正确的线程输出

java - Android Java - 解析 "76"时出现 NumberFormatException

java - Spring 可以解析和注入(inject)属性文件吗?

java - 无法@Autowire存储库接口(interface)Spring Boot

unit-testing - Selenium 测试后清理数据

java - 为什么这个 O(n^2) 代码的执行速度比 O(n) 快?

java - 如何在 freeBSD sh 的命令行中获取 java 进程的进程 ID

java - 在 Thymeleaf 数组中输入

Jenkins 上的 Android 单元测试