Fork me on GitHub

SSM:Struts2+Spring+Mybatis+Jersey Web 项目单元测试

目录

  1. 1. 前言
  2. 2. 测试项目配置
  3. 3. Service 单元测试
    1. 3.1. 新建测试类
    2. 3.2. 为测试类添加注解
    3. 3.3. 填写测试内容
    4. 3.4. 运行单元测试
      1. 3.4.1. 运行该测试类的所有单元测试
      2. 3.4.2. 运行指定的单元测试
      3. 3.4.3. 输出日志
  4. 4. 参考文章

前言

在参与写web项目的时候越到后期发现对自己写的 Service 以及 Controller 进行单元测试的必要性,因为有些项目已经开始上线测试,需要保证接口的稳定性,而且涉及到多人协作完成一个需求,需要把其划分为不同的部分,保证自己开发的部分的稳定,方便其他人继续其他的步骤。
Struts2+Spring+Mybatis+Jersey Web 项目下对 Service 的单元测试

测试项目配置

SSM项目配置参考另一篇文章:Struts2+Spring+Mybatis+Jersey Web 项目搭建或者直接下载源码:https://github.com/lulee007/ssm_demo tag:basic-ssm

  • 配置单元测试
    打开项目pom.xml添加两个依赖项到dependencies节点下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <!--junit4 ,如果已经有了其他版本,只需换个版本号即可4.11-->
    <!-- 单元测试依赖-->
    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
    </dependency>
    <!-- 单元测试里会用到注入,注入spring管理的bean-->
    <dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
    <scope>test</scope>
    </dependency>
    <!-- spring单元测试的依赖-->
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${spring.version}</version>
    <scope>test</scope>
    </dependency>

Service 单元测试

新建测试类

打开UserServiceImpl.java文件,然后把光标放到UserServiceImpl单词上,这时按快捷键command+enter就会弹出快捷菜单,选择第一个, Create test class, 然后在弹出的窗口中,选择测试类库junit4,然后勾选需要要生成测试方法的,最后按ok就会在test目录下生成对应的测试类了。
create unit test

为测试类添加注解

为了能让这个测试类在spring环境下进行运行,需要对其进行额外的配置。
复制一下注解代码到UserServiceImplTest类顶部:

1
2
3
4
5
6
7
8
9
@RunWith( SpringJUnit4ClassRunner.class ) //指定单元测试运行类
@ContextConfiguration( locations = { "classpath*:config/spring/applicationContext-*.xml" } ) //指定Spring配置文件的位置
//很多情况下单元测试离不开事务,下面的注解指明使用的事务管理器
//如果defaultRollback为true,测试运行结束后,默认回滚事务,不影响数据库
@TransactionConfiguration( transactionManager = "dataSourceTransactionManager", defaultRollback = true )
@Transactional //指定默认所有测试方法的事务特性
public class UserServiceImplTest {
...
}

  • @RunWith( SpringJUnit4ClassRunner.class ): 用来指定单元测试运行类
  • @ContextConfiguration( locations = { "classpath*:config/spring/applicationContext-*.xml" } ): 指定Spring配置文件的位置
  • @TransactionConfiguration( transactionManager = "dataSourceTransactionManager", defaultRollback = true ): 很多情况下单元测试测试和数据库相关的时候离不开事务,这里的注解指明使用的事务管理器,如果defaultRollback为true,测试运行结束后,默认回滚事务,不影响数据库
  • @Transactional 指定默认所有测试方法的事务特性

填写测试内容

添加一个查询和保存用户的测试代码,完整的测试内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.lulee007.ssm.service;
import com.lulee007.ssm.pojo.User;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
import javax.inject.Inject;
import java.util.List;
import static org.junit.Assert.*;
/**
* Created by lulee007 on 16/1/26.
*/
@RunWith( SpringJUnit4ClassRunner.class ) //指定单元测试运行类
@ContextConfiguration( locations = { "classpath*:config/spring/applicationContext-*.xml" } ) //指定Spring配置文件的位置
//很多情况下单元测试离不开事务,下面的注解指明使用的事务管理器
//如果defaultRollback为true,测试运行结束后,默认回滚事务,不影响数据库
@TransactionConfiguration( transactionManager = "dataSourceTransactionManager", defaultRollback = true )
@Transactional //指定默认所有测试方法的事务特性
public class UserServiceImplTest {
//该字段本身由Spring自动注入
@Inject
UserService userService;
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testFindUser() throws Exception {
//事先已经在数据库插入了一条数据
List<User> allUsers=userService.findUser();
assertEquals(allUsers.size(),1);
}
@Test
public void testSaveUser() throws Exception {
//测试 插入一条新数据
User user=new User();
user.setUsername("lulee007");
Boolean result=userService.saveUser(user);
assertEquals(result,Boolean.TRUE);
}
}

运行单元测试

运行该测试类的所有单元测试

将光标放到测试类内部任何位置,但不要放在方法内部,使用快捷键control+shitf+ R或者,右击选择弹出菜单的Run UserServiceImplTest,运行测试类的所有测试方法:
run test all

运行指定的单元测试

将光标放到方法体内部(方法的大话括弧中间即可),使用快捷键control+shitf+ R或者,右击选择弹出菜单的Run UserServiceImplTest.xxxx,运行指定的测试方法:
run single test

输出日志

默认配置好了,在终端只能看到很简单的输出:

1
2
3
log4j:WARN No appenders could be found for logger (org.springframework.test.context.junit4.SpringJUnit4ClassRunner).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

这个时候需要配置log4j,在test/java/com/lulee007/ssm/新建JUnit4ClassRunner.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.lulee007.ssm;
import org.junit.internal.runners.InitializationError;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Log4jConfigurer;
import java.io.FileNotFoundException;
/**
* Created by lulee007 on 16/1/19.
*/
public class JUnit4ClassRunner extends SpringJUnit4ClassRunner {
static {
try {
Log4jConfigurer.initLogging("classpath:config/log4j/log4j.xml");
} catch (FileNotFoundException ex) {
System.err.println("Cannot Initialize log4j");
}
}
public JUnit4ClassRunner(Class<?> clazz) throws org.junit.runners.model.InitializationError {
super(clazz);
}
}

修改我们的测试类UserServiceImplTest@RunWith()部分,将原有的SpringJUnit4ClassRunner.class替换为我们刚才新建的JUnit4ClassRunner.class,重新运行我们的单元测试:
unit test log
这是时候可以看到所有的日志信息了,方便调试定位。

参考文章

本文总阅读量