我想在运行Tomcat和Spring 4时进行简单的集成测试,注入spring组件并使用Tomcat中现有的数据源配置。我不想两次配置我的DataSource。
包括我的数据源在内的所有内容都在文件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,但我并不完全理解如何在提供我的DataSource的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提供的上下文提供我的测试,包括我的数据源配置?我不想两次设置数据源连接凭据。
答案 0 :(得分:0)
解决了它。回顾一下这个问题: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 {
...
答案 1 :(得分:0)
TomcatJNDI为这个问题提供了一个舒适的解决方案。它基于Tomcat的JNDI系统,只在不启动服务器的情况下初始化Tomcat的JNDI环境。因此,您可以在测试中或在任何Java SE应用程序中访问Tomcat配置文件中配置的所有资源。用法很简单,e。克。
TomcatJNDI tomcatJNDI = new TomcatJNDI();
tomcatJNDI.processContextXml(contextXmlFile);
tomcatJNDI.start();
DataSource ds = (DataSource) InitialContext.doLookup("java:comp/env/path/to/datasource");