仅用于 Spring 应用程序中的 JUnit 测试的单独数据库
Posted
技术标签:
【中文标题】仅用于 Spring 应用程序中的 JUnit 测试的单独数据库【英文标题】:Separate DB just for JUnit tests in Spring app 【发布时间】:2014-02-05 11:38:28 【问题描述】:我正在使用文件内 HSQL 数据库为我的 Spring 应用程序编写单元测试。我不想用测试数据污染这个数据库,所以我正在尝试设置另一个内存中的 HSQL 数据库实例以用于测试。
在我的抽象测试类中,我导入测试应用程序上下文 XML 配置:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/testingContext.xml")
@Transactional
public abstract class AbstractDaoForTesting
testingContext.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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
">
<jdbc:embedded-database id="dataSource" type="HSQL" />
<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.se.micom" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="myEmf" />
</bean>
<tx:annotation-driven />
<bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean id="characteristicDao" class="com.se.micom.dao.CharacteristicDaoImpl"/>
<bean id="functionalityDao" class="com.se.micom.dao.FunctionalityDaoImpl"/>
<bean id="segmentDao" class="com.se.micom.dao.SegmentDaoImpl"/>
<bean id="segmentService" class="com.se.micom.service.SegmentServiceImpl"/>
<bean id="functionalityService" class="com.se.micom.service.FunctionalityServiceImpl"/>
<bean id="characteristicService" class="com.se.micom.service.CharacteristicServiceImpl" />
</beans>
到目前为止,内存中的 HSQL db 在测试中运行良好。
然而,一旦我在我的项目中引入persistence.xml
in src/main/resources/META-INF
单元测试就开始使用这个持久性单元,而不是来自testingContext.xml
的那个。
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="micomPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.se.micom.dao.domain.Characteristic</class>
<class>com.se.micom.dao.domain.Functionality</class>
<class>com.se.micom.dao.domain.Segment</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:file:D:\workspace_java\Micom2\db\micom"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
<property name="javax.persistence.jdbc.user" value="sa"/>
</properties>
</persistence-unit>
</persistence>
这个配置有什么问题?为什么测试“更喜欢”使用persistence.xml
中定义的db?
【问题讨论】:
【参考方案1】:您的问题是 Spring 配置文件的完美示例。如果您希望使用某个 bean,那么让多个 bean 在您的上下文中同时做同样的事情总是有问题的。
您应该有两个不同的配置文件,"prod"
和 "test"
,并使用 <beans profile="XYZ"> ... </beans>
将您的 bean 声明相应地包装在 xml 配置中。可以在here 找到更广泛的示例。
然后您可以使用 @Profile("test")
注释您的测试,它应该使用正确的数据库。
【讨论】:
以上是关于仅用于 Spring 应用程序中的 JUnit 测试的单独数据库的主要内容,如果未能解决你的问题,请参考以下文章
用于 Spring Boot 应用程序的 JUnit @BeforeClass 非静态工作