依赖引入

为了简化依赖,直接引入引入SpringBoot POM,但是只用Spring+SpringTest来使用单测

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-test</artifactId>
  4. </dependency>
  5. <!-- spring-boot-starter-test已经内置junit,这里是显示引入,表示使用Junit4 -->
  6. <dependency>
  7. <groupId>junit</groupId>
  8. <artifactId>junit</artifactId>
  9. <version>4.12</version>
  10. </dependency>

XML-Based

ContextConfiguration+Xml+Properties+Component-scan

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(locations = "classpath:beans.xml")
  3. public class SpringJunitTest implements ApplicationContextAware {
  4. }

外部XML可以配置properties文件,或component-scan

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. 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">
  6. <context:component-scan base-package="com.spring"/>
  7. <context:property-placeholder location="application.properties"/>
  8. <!-- 事务注解 -->
  9. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  10. <property name="dataSource" ref="grus"/>
  11. </bean>
  12. <tx:annotation-driven transaction-manager="transactionManager"/>
  13. </beans>

ContextConfiguration+XML+Properties+事物回滚

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @TestPropertySource(locations = {"classpath:spring/config-env.properties"})
  3. @ContextConfiguration(locations = {"classpath*:spring/applicationContext*.xml", "classpath*:springmvc/springmvc-backend.xml"})
  4. @Transactional
  5. @Rollback
  6. public abstact class IntegrationTestBase implements ApplicationContextAware {
  7. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. 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">
  6. <!-- 事务注解 -->
  7. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  8. <property name="dataSource" ref="grus"/>
  9. </bean>
  10. <tx:annotation-driven transaction-manager="transactionManager"/>
  11. </beans>

JavaConfig-Based(零XML)

@Configuration与XML 配置类似

ContextConfiguration+内部配置类+AnnotationConfigContextLoader

如果使用了AnnotationConfigContextLoader,则需要指定配置类,也就是@Configuration标注的Class
如果ContextConfiguration未指定classes,也就是未使用独立的配置类,则AnnotationConfigContextLoader会从当前类里查找静态内部类作为配置类,如果有则扫描Bean。
注意:当前的静态内部类不能是final,不能是private.

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(loader = AnnotationConfigContextLoader.class)
  3. public class SpringJunitTest implements ApplicationContextAware {
  4. private ApplicationContext applicationContext;
  5. @Configuration
  6. static class ExtraConfig {
  7. // this bean will be injected into the OrderServiceTest class
  8. @Bean
  9. public OrderService orderService() {
  10. OrderService orderService = new OrderService();
  11. // set properties, etc.
  12. return orderService;
  13. }
  14. }
  15. }
  16. @RunWith(SpringJUnit4ClassRunner.class)
  17. @ContextConfiguration() // 走默认的Loader,自动决策
  18. public class SpringJunitTest implements ApplicationContextAware {
  19. private ApplicationContext applicationContext;
  20. @Configuration
  21. static class ExtraConfig {
  22. // this bean will be injected into the OrderServiceTest class
  23. @Bean
  24. public OrderService orderService() {
  25. OrderService orderService = new OrderService();
  26. // set properties, etc.
  27. return orderService;
  28. }
  29. }
  30. }

ContextConfiguration+独立配置类+Loader

指定ContextConfiguration的classes为某个配置类或某些配置类。如果未指定loader,默认为:DelegatingSmartContextLoader,会自动决策. 如果加载的是XML配置,则使用:GenericXmlContextLoader, 如果是配置类,则使用AnnotationConfigContextLoader。

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. // loader=AnnotationConfigContextLoader 可默认不写
  3. @ContextConfiguration(classes = App.class, loader = AnnotationConfigContextLoader.class)
  4. public class SpringJunitTest implements ApplicationContextAware {
  5. }
  6. @RunWith(SpringJUnit4ClassRunner.class)
  7. // loader=AnnotationConfigContextLoader 可默认不写, 走自动识别Loader
  8. @ContextConfiguration(classes = App.class)
  9. public class SpringJunitTest implements ApplicationContextAware {
  10. }
  11. @ComponentScan(basePackages = {"com.spring"})
  12. @Configuration
  13. public class App {
  14. }

独立配置类,与JavaConfig用法一致,可使用@ComponentScan,@Import, @ImportResource.
当然不建议Import XML文件,因为推荐使用零配置,都采用注解风格。

  1. @ComponentScan(basePackages = {"com.spring"})
  2. @Configuration
  3. @ImportResource("classpath:app.xml")
  4. @Import(User.class)
  5. public class App {
  6. }

ContextConfiguration+配置继承

XML-Based

  1. @ContextConfiguration("base-context.xml")
  2. @RunWith(SpringJUnit4ClassRunner.class)
  3. public class BaseTest {
  4. // ...
  5. }
  6. @ContextConfiguration("extended-context.xml")
  7. public class ExtendedTest extends BaseTest {
  8. // ...
  9. }

JavaConfig-Based

  1. @ContextConfiguration(classes=BaseConfig.class)
  2. @RunWith(SpringJUnit4ClassRunner.class)
  3. public class BaseTest {
  4. // ...
  5. }
  6. @ContextConfiguration(classes=ExtendedConfig.class)
  7. public class ExtendedTest extends BaseTest {
  8. // ...
  9. }

ContextConfiguration+Profile

XML-Based

使用@ActiveProfiles

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. // ApplicationContext will be loaded from "classpath:/app-config.xml"
  3. @ContextConfiguration("/app-config.xml")
  4. @ActiveProfiles("dev")
  5. public class TransferServiceTest {
  6. @Autowired
  7. private TransferService transferService;
  8. @Test
  9. public void testTransferService() {
  10. // test the transferService
  11. }
  12. }
  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:jdbc="http://www.springframework.org/schema/jdbc"
  4. xmlns:jee="http://www.springframework.org/schema/jee"
  5. xsi:schemaLocation="...">
  6. <bean id="transferService" class="com.bank.service.internal.DefaultTransferService">
  7. <constructor-arg ref="accountRepository"/>
  8. <constructor-arg ref="feePolicy"/>
  9. </bean>
  10. <bean id="accountRepository" class="com.bank.repository.internal.JdbcAccountRepository">
  11. <constructor-arg ref="dataSource"/>
  12. </bean>
  13. <bean id="feePolicy" class="com.bank.service.internal.ZeroFeePolicy"/>
  14. <beans profile="dev">
  15. <jdbc:embedded-database id="dataSource">
  16. <jdbc:script location="classpath:com/bank/config/sql/schema.sql"/>
  17. <jdbc:script location="classpath:com/bank/config/sql/test-data.sql"/>
  18. </jdbc:embedded-database>
  19. </beans>
  20. <beans profile="production">
  21. <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/>
  22. </beans>
  23. </beans>

JavaConfig-Based

  1. @Configuration
  2. @Profile("dev")
  3. public class StandaloneDataConfig {
  4. @Bean
  5. public DataSource dataSource() {
  6. return new EmbeddedDatabaseBuilder()
  7. .setType(EmbeddedDatabaseType.HSQL)
  8. .addScript("classpath:com/bank/config/sql/schema.sql")
  9. .addScript("classpath:com/bank/config/sql/test-data.sql")
  10. .build();
  11. }
  12. }
  13. @Configuration
  14. @Profile("production")
  15. public class JndiDataConfig {
  16. @Bean
  17. public DataSource dataSource() throws Exception {
  18. Context ctx = new InitialContext();
  19. return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
  20. }
  21. }
  22. @Configuration
  23. public class TransferServiceConfig {
  24. @Autowired DataSource dataSource;
  25. @Bean
  26. public TransferService transferService() {
  27. return new DefaultTransferService(accountRepository(), feePolicy());
  28. }
  29. @Bean
  30. public AccountRepository accountRepository() {
  31. return new JdbcAccountRepository(dataSource);
  32. }
  33. @Bean
  34. public FeePolicy feePolicy() {
  35. return new ZeroFeePolicy();
  36. }
  37. }

测试类

  1. package com.bank.service;
  2. @RunWith(SpringJUnit4ClassRunner.class)
  3. @ContextConfiguration(loader=AnnotationConfigContextLoader.class,
  4. classes={TransferServiceConfig.class, StandaloneDataConfig.class, JndiDataConfig.class})
  5. @ActiveProfiles("dev")
  6. public class TransferServiceTest {
  7. @Autowired
  8. private TransferService transferService;
  9. @Test
  10. public void testTransferService() {
  11. // test the transferService
  12. }
  13. }