用于 JUnit 测试的多个 Spring 数据源
Multiple Spring datasources for JUnit test
我有这么简单的 class 用于 JUnit 测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/mysql-datasource-context.xml"})
public class EmployeeDAOTest {
@Autowired
EmployeeDao employeeDao;
@Test
public void findAllTest() {
assertTrue(employeeDao.findByName("noname").size() == 0);
}
}
mysql-datasource-context.xml 的内容如下所示:
<context:component-scan base-package="my.packages.*"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/project"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="my.packages.entity"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
现在测试 运行 对我的 mysql 数据库没有问题。
重点是我还有一个 postgres 数据库,我需要对 mysql 和 postgres 数据库进行每个测试 运行。
我想到的唯一解决方案是使用完全相同的测试再创建一个测试 class,但将其注释为
@ContextConfiguration(locations = {"classpath:/postgres -datasource-context.xml"})
并为其再创建一个数据源上下文文件。不幸的是,这种方式看起来不是一个好的解决方案。
有没有更好的方法来解决我的问题?
一看就是spring多数据源配置,其实你可以通过google得到很多帖子,或者在Whosebug
中快速搜索它
示例:
Spring Boot Multiple Datasource
我可以想象的另一种解决方案是使用 spring 配置文件。
我总是发现最好有一个包含其他文件的顶级应用上下文文件:
appcontext-root.xml
<beans>
<import resource="appcontext-services.xml"/>
<import resource="appcontext-db.xml"/>
</beans>
然后您的应用程序可以 运行 上下文 - root.xml,但您的测试可以测试一个(或多个)较低级别的文件。
如果您想要一个可交换的后端,您可以考虑使用 PropertyPlaceHolderConfigurer。
例如:
<import resource="appcontext-db-${vendor}.xml"/>
并且有一个 appcontext-db-mysql.xml、appcontext-db-postgres.xml 以及 System.setProperty("vendor", "mysql")
我认为最简单的解决方案是保留测试 class 作为基础测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/mysql-datasource-context.xml"})
public class EmployeeDAOTest {
@Autowired
EmployeeDao employeeDao;
@Test
public void findAllTest() {
assertTrue(employeeDao.findByName("noname").size() == 0);
}
}
然后用自己的配置为 postgres 创建一个 empty subclass:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/postgres-datasource-context.xml"}, inheritLocations=false)
public class EmployeeDAOTestPostgres extends EmployeeDAOTest {
}
正如其他人所建议的那样,您可以更改 Spring 配置文件以便只有一个;例如,您可以将数据源放在单独的上下文中并导入它或使用配置文件(例如,请参见 here)
我有这么简单的 class 用于 JUnit 测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/mysql-datasource-context.xml"})
public class EmployeeDAOTest {
@Autowired
EmployeeDao employeeDao;
@Test
public void findAllTest() {
assertTrue(employeeDao.findByName("noname").size() == 0);
}
}
mysql-datasource-context.xml 的内容如下所示:
<context:component-scan base-package="my.packages.*"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/project"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="my.packages.entity"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
现在测试 运行 对我的 mysql 数据库没有问题。
重点是我还有一个 postgres 数据库,我需要对 mysql 和 postgres 数据库进行每个测试 运行。
我想到的唯一解决方案是使用完全相同的测试再创建一个测试 class,但将其注释为
@ContextConfiguration(locations = {"classpath:/postgres -datasource-context.xml"})
并为其再创建一个数据源上下文文件。不幸的是,这种方式看起来不是一个好的解决方案。
有没有更好的方法来解决我的问题?
一看就是spring多数据源配置,其实你可以通过google得到很多帖子,或者在Whosebug
中快速搜索它示例: Spring Boot Multiple Datasource
我可以想象的另一种解决方案是使用 spring 配置文件。
我总是发现最好有一个包含其他文件的顶级应用上下文文件:
appcontext-root.xml
<beans>
<import resource="appcontext-services.xml"/>
<import resource="appcontext-db.xml"/>
</beans>
然后您的应用程序可以 运行 上下文 - root.xml,但您的测试可以测试一个(或多个)较低级别的文件。
如果您想要一个可交换的后端,您可以考虑使用 PropertyPlaceHolderConfigurer。
例如:
<import resource="appcontext-db-${vendor}.xml"/>
并且有一个 appcontext-db-mysql.xml、appcontext-db-postgres.xml 以及 System.setProperty("vendor", "mysql")
我认为最简单的解决方案是保留测试 class 作为基础测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/mysql-datasource-context.xml"})
public class EmployeeDAOTest {
@Autowired
EmployeeDao employeeDao;
@Test
public void findAllTest() {
assertTrue(employeeDao.findByName("noname").size() == 0);
}
}
然后用自己的配置为 postgres 创建一个 empty subclass:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/postgres-datasource-context.xml"}, inheritLocations=false)
public class EmployeeDAOTestPostgres extends EmployeeDAOTest {
}
正如其他人所建议的那样,您可以更改 Spring 配置文件以便只有一个;例如,您可以将数据源放在单独的上下文中并导入它或使用配置文件(例如,请参见 here)