• 参考文章
  • 代码实例:ideaProjects/thz/thz-manager-web/test

普通测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:config/applicationContext.xml") 
    //classpath:在当前项目查找;classpath*:在所有依赖的jar包的classpath下找
@Transactional
public class UserServiceImplTest {
    @Resource
    private UserService userService;

    @Test
    public void addUser() {
        User user=new User();
        user.setUsername("test");
        user.setPassword("123456");
        int result=userService.addUser(user);
        Assert.assertThat(result,is(1));
    }
}
  • @RunWith: 运行器。@RunWith(JUnit4.class)就是指用JUnit4来运行测试;@RunWith(SpringJUnit4ClassRunner.class)则是运行于Spring测试环境。
  • @ContextConfiguration:当我们想要在测试类使用@Resource注解注入bean时,只需要添加该注解指明去哪里能找到这些bean即可。我们知道注册bean的方法有:
  1. 在xml中注册bean:先定义好这个类然后到xml中注册成bean。

    <bean id="cacheManager" 
          class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" value="ehcacheManager"/>
    </bean>
    
  • 那么测试时:
@ContextConfiguration(locations = "classpath:spring-beans.xml")
  • 代码示例:ideaProjects\shirochapter12\ShiroTest
  1. 定义类时顺便加@Component等注解注册成bean,再扫描这些bean,扫描bean的方式也分两种:

i. 在xml中配置component-scan:

<context:component-scan base-package="com.haien.chapter16">
  • 那么测试时引入该配置文件即可:
@ContextConfiguration(locations = "classpath:spring-config.xml")

ii. 在Java configuration类中加@ComponentScan

@ComponentScan(basePackages = "com.haien.sping.cache.service")
public class AnnotationCacheConfig {

}
  • 那么测试时引入这个类即可:
@ContextConfiguration(classes=AnnotationCacheConfig.class)
  • 多个则:
@ContextConfiguration(classes = {WebMvcConfig.class, HibernateConfig.class})
  • 代码示例:ideaProjects\spring-cache\test\UserServiceTest
  • 参考文章

controller层测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:config/applicationContext.xml","classpath:config/spring-mvc.xml"})
public class GoodsControllerTest {

    @Resource
    private GoodsController goodsController;

    private MockMvc mockMvc;

    @Before
    public void setUp() {
        mockMvc=MockMvcBuilders.standaloneSetup(goodsController).build(); //缺少这一步抛异常:No mapping found for HTTP request with URI [...] in DispatcherServlet;找不到路径
    }

    @Test
    public void queryGoods() throws Exception {
        String url="/goods/query?pageNum=1&rows=5&type=液体";
        ResultActions resultActions=mockMvc.perform(MockMvcRequestBuilders.get(url));
        MvcResult mvcResult=resultActions.andReturn();
        String result=mvcResult.getResponse().getContentAsString();
        System.out.println("客户端获得反馈数据:"+result);
        //也可以从response中获取状态码、header、cookies...
        System.out.println(mvcResult.getResponse().getStatus());
    }
}

事务自动回滚

  • 引入依赖

    <dependency> <!--用于开启事务,否则测试将无法自动回滚-->
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    
  • applicationContext.xml:配置事务管理器、开启事务

    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!--开启事务-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
  • 创建单元测试,添加@Transactional注解

@RunWith(SpringJUnit4ClassRunner.class) //告诉Junit使用Spring TestRunner
@ContextConfiguration(locations = {"classpath:spring-beans.xml",
    "classpath:spring-shiro.xml"}) //指定bean注入的配置文件
@Transactional
public class ShiroTest {
    @Autowired
    protected RoleService roleService;

    @Test
    public void addRole(){
        Role r = new Role("test", "测试", Boolean.TRUE);
        r=roleService.createRole(r);
        Assert.assertThat(r.getId(),is(51L));
    }
}
  • 如果前面不配置事务管理器并开启事务的话,测试类加@Transactional不会报错,但也不会回滚。