依赖引入
为了简化依赖,直接引入引入SpringBoot POM,但是只用Spring+SpringTest来使用单测
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><!-- spring-boot-starter-test已经内置junit,这里是显示引入,表示使用Junit4 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>
XML-Based
ContextConfiguration+Xml+Properties+Component-scan
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:beans.xml")public class SpringJunitTest implements ApplicationContextAware {}
外部XML可以配置properties文件,或component-scan
<?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:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.spring"/><context:property-placeholder location="application.properties"/><!-- 事务注解 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="grus"/></bean><tx:annotation-driven transaction-manager="transactionManager"/></beans>
ContextConfiguration+XML+Properties+事物回滚
@RunWith(SpringJUnit4ClassRunner.class)@TestPropertySource(locations = {"classpath:spring/config-env.properties"})@ContextConfiguration(locations = {"classpath*:spring/applicationContext*.xml", "classpath*:springmvc/springmvc-backend.xml"})@Transactional@Rollbackpublic abstact class IntegrationTestBase implements ApplicationContextAware {}
<?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:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!-- 事务注解 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="grus"/></bean><tx:annotation-driven transaction-manager="transactionManager"/></beans>
JavaConfig-Based(零XML)
ContextConfiguration+内部配置类+AnnotationConfigContextLoader
如果使用了AnnotationConfigContextLoader,则需要指定配置类,也就是@Configuration标注的Class
如果ContextConfiguration未指定classes,也就是未使用独立的配置类,则AnnotationConfigContextLoader会从当前类里查找静态内部类作为配置类,如果有则扫描Bean。
注意:当前的静态内部类不能是final,不能是private.
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(loader = AnnotationConfigContextLoader.class)public class SpringJunitTest implements ApplicationContextAware {private ApplicationContext applicationContext;@Configurationstatic class ExtraConfig {// this bean will be injected into the OrderServiceTest class@Beanpublic OrderService orderService() {OrderService orderService = new OrderService();// set properties, etc.return orderService;}}}@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration() // 走默认的Loader,自动决策public class SpringJunitTest implements ApplicationContextAware {private ApplicationContext applicationContext;@Configurationstatic class ExtraConfig {// this bean will be injected into the OrderServiceTest class@Beanpublic OrderService orderService() {OrderService orderService = new OrderService();// set properties, etc.return orderService;}}}
ContextConfiguration+独立配置类+Loader
指定ContextConfiguration的classes为某个配置类或某些配置类。如果未指定loader,默认为:DelegatingSmartContextLoader,会自动决策. 如果加载的是XML配置,则使用:GenericXmlContextLoader, 如果是配置类,则使用AnnotationConfigContextLoader。
@RunWith(SpringJUnit4ClassRunner.class)// loader=AnnotationConfigContextLoader 可默认不写@ContextConfiguration(classes = App.class, loader = AnnotationConfigContextLoader.class)public class SpringJunitTest implements ApplicationContextAware {}@RunWith(SpringJUnit4ClassRunner.class)// loader=AnnotationConfigContextLoader 可默认不写, 走自动识别Loader@ContextConfiguration(classes = App.class)public class SpringJunitTest implements ApplicationContextAware {}@ComponentScan(basePackages = {"com.spring"})@Configurationpublic class App {}
独立配置类,与JavaConfig用法一致,可使用@ComponentScan,@Import, @ImportResource.
当然不建议Import XML文件,因为推荐使用零配置,都采用注解风格。
@ComponentScan(basePackages = {"com.spring"})@Configuration@ImportResource("classpath:app.xml")@Import(User.class)public class App {}
ContextConfiguration+配置继承
XML-Based
@ContextConfiguration("base-context.xml")@RunWith(SpringJUnit4ClassRunner.class)public class BaseTest {// ...}@ContextConfiguration("extended-context.xml")public class ExtendedTest extends BaseTest {// ...}
JavaConfig-Based
@ContextConfiguration(classes=BaseConfig.class)@RunWith(SpringJUnit4ClassRunner.class)public class BaseTest {// ...}@ContextConfiguration(classes=ExtendedConfig.class)public class ExtendedTest extends BaseTest {// ...}
ContextConfiguration+Profile
XML-Based
使用@ActiveProfiles
@RunWith(SpringJUnit4ClassRunner.class)// ApplicationContext will be loaded from "classpath:/app-config.xml"@ContextConfiguration("/app-config.xml")@ActiveProfiles("dev")public class TransferServiceTest {@Autowiredprivate TransferService transferService;@Testpublic void testTransferService() {// test the transferService}}
<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:jee="http://www.springframework.org/schema/jee"xsi:schemaLocation="..."><bean id="transferService" class="com.bank.service.internal.DefaultTransferService"><constructor-arg ref="accountRepository"/><constructor-arg ref="feePolicy"/></bean><bean id="accountRepository" class="com.bank.repository.internal.JdbcAccountRepository"><constructor-arg ref="dataSource"/></bean><bean id="feePolicy" class="com.bank.service.internal.ZeroFeePolicy"/><beans profile="dev"><jdbc:embedded-database id="dataSource"><jdbc:script location="classpath:com/bank/config/sql/schema.sql"/><jdbc:script location="classpath:com/bank/config/sql/test-data.sql"/></jdbc:embedded-database></beans><beans profile="production"><jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/></beans></beans>
JavaConfig-Based
@Configuration@Profile("dev")public class StandaloneDataConfig {@Beanpublic DataSource dataSource() {return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).addScript("classpath:com/bank/config/sql/schema.sql").addScript("classpath:com/bank/config/sql/test-data.sql").build();}}@Configuration@Profile("production")public class JndiDataConfig {@Beanpublic DataSource dataSource() throws Exception {Context ctx = new InitialContext();return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");}}@Configurationpublic class TransferServiceConfig {@Autowired DataSource dataSource;@Beanpublic TransferService transferService() {return new DefaultTransferService(accountRepository(), feePolicy());}@Beanpublic AccountRepository accountRepository() {return new JdbcAccountRepository(dataSource);}@Beanpublic FeePolicy feePolicy() {return new ZeroFeePolicy();}}
测试类
package com.bank.service;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(loader=AnnotationConfigContextLoader.class,classes={TransferServiceConfig.class, StandaloneDataConfig.class, JndiDataConfig.class})@ActiveProfiles("dev")public class TransferServiceTest {@Autowiredprivate TransferService transferService;@Testpublic void testTransferService() {// test the transferService}}
