博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在Spring中整合JUnit单元测试
阅读量:7231 次
发布时间:2019-06-29

本文共 9576 字,大约阅读时间需要 31 分钟。

一 简介

在Java Web开发中,通常我们会开发很多的功能代码。在代码正式使用之前,为了确保代码能够正确实现我们预期的功能,最好是添加一些简单代码对代码逻辑进行测试。很显然,JUnit就是一个不错的单元测试工具,同时在Spring中我们也可以很方便地引入JUnit进行测试

二 代码实例

(1)引入必需的jar包:

这里除了Spring以及其他模块所需要的jar包之外,还需要引入:

  • spring-test-4.2.3.RELEASE.jar

  • junit-4.10.jar

注:jar包版本使用最新稳定版即可

(2)测试项目目录结构以及配置:

上面图中的一些目录是我自己新建的,为的就是将不同功能的文件分隔开。这个Demo项目采用的技术是:Spring + Spring MVC + Mybatis + MySQL + Druid连接池

context.xml文件是一些基本配置;springmvc-servlet.xml文件是 Spring MVC相关的配置;sql-map-config.xml文件是Mybatis相关配置。下面我粘贴下web.xml文件和context.xml文件的代码供大家参考,其他的一些配置文件跟这里关系不大就不粘贴出来了

i)web.xml:

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<
web-app 
xmlns
=
"http://xmlns.jcp.org/xml/ns/javaee" 
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
    
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
      
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    
version
=
"3.1"
>
 
    
<
context-param
>
        
<
param-name
>contextConfigLocation</
param-name
>
        
<
param-value
>
            
classpath:context/context.xml
        
</
param-value
>
    
</
context-param
>
 
    
<
listener
>
        
<
listener-class
>org.springframework.web.context.ContextLoaderListener</
listener-class
>
    
</
listener
>
    
<
listener
>
        
<
listener-class
>org.springframework.web.context.request.RequestContextListener</
listener-class
>
    
</
listener
>
    
<
servlet
>
        
<
servlet-name
>springmvc</
servlet-name
>
        
<
servlet-class
>org.springframework.web.servlet.DispatcherServlet</
servlet-class
>
        
<
init-param
>
            
<
param-name
>contextConfigLocation</
param-name
>
            
<
param-value
>classpath:context/springmvc-servlet.xml</
param-value
>
        
</
init-param
>
        
<
load-on-startup
>1</
load-on-startup
>
    
</
servlet
>
 
    
<
servlet-mapping
>
        
<
servlet-name
>springmvc</
servlet-name
>
        
<!-- <url-pattern>*.html</url-pattern> -->
        
<
url-pattern
>*.html</
url-pattern
>
    
</
servlet-mapping
>
 
    
<
filter
>
        
<
filter-name
>characterEncodingFilter</
filter-name
>
        
<
filter-class
>org.springframework.web.filter.CharacterEncodingFilter</
filter-class
>
        
<
init-param
>
            
<
param-name
>encoding</
param-name
>
            
<
param-value
>UTF-8</
param-value
>
        
</
init-param
>
    
</
filter
>
    
<
filter-mapping
>
        
<
filter-name
>characterEncodingFilter</
filter-name
>
        
<
url-pattern
>/*</
url-pattern
>
    
</
filter-mapping
>
 
    
<
servlet
>
        
<
servlet-name
>DruidStatView</
servlet-name
>
        
<
servlet-class
>com.alibaba.druid.support.http.StatViewServlet</
servlet-class
>
    
</
servlet
>
    
<
servlet-mapping
>
        
<
servlet-name
>DruidStatView</
servlet-name
>
        
<
url-pattern
>/druid/*</
url-pattern
>
    
</
servlet-mapping
>
    
<
filter
>
        
<
filter-name
>druidWebStatFilter</
filter-name
>
        
<
filter-class
>com.alibaba.druid.support.http.WebStatFilter</
filter-class
>
        
<
init-param
>
            
<
param-name
>exclusions</
param-name
>
            
<
param-value
>/public/*,*.js,*.css,/druid*,*.jsp,*.swf</
param-value
>
        
</
init-param
>
        
<
init-param
>
            
<
param-name
>principalSessionName</
param-name
>
            
<
param-value
>sessionInfo</
param-value
>
        
</
init-param
>
        
<
init-param
>
            
<
param-name
>profileEnable</
param-name
>
            
<
param-value
>true</
param-value
>
        
</
init-param
>
    
</
filter
>
    
<
filter-mapping
>
        
<
filter-name
>druidWebStatFilter</
filter-name
>
        
<
url-pattern
>/*</
url-pattern
>
    
</
filter-mapping
>
 
</
web-app
>

ii)context.xml:

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<?
xml 
version
=
"1.0" 
encoding
=
"UTF-8"
?>
<
beans 
xmlns
=
"http://www.springframework.org/schema/beans"
    
xmlns:cache
=
"http://www.springframework.org/schema/cache" 
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
    
xmlns:jee
=
"http://www.springframework.org/schema/jee"
    
xsi:schemaLocation="http://www.springframework.org/schema/beans 
            
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            
http://www.springframework.org/schema/jee 
            
http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
            
http://www.springframework.org/schema/aop 
            
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
            
http://www.springframework.org/schema/context 
            
http://www.springframework.org/schema/context/spring-context-4.0.xsd
            
http://www.springframework.org/schema/cache  
             
http://www.springframework.org/schema/cache/spring-cache-4.0.xsd  
            
http://www.springframework.org/schema/tx 
            
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"
    
xmlns:context
=
"http://www.springframework.org/schema/context" 
xmlns:tx
=
"http://www.springframework.org/schema/tx"
    
xmlns:aop
=
"http://www.springframework.org/schema/aop"
>
 
    
<
bean 
id
=
"propertyConfigurer"
        
class
=
"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
>
        
<
property 
name
=
"locations"
>
            
<
list
>
                
<
value
>classpath:jdbc.properties</
value
>
            
</
list
>
        
</
property
>
    
</
bean
>
 
    
<!-- Druid连接池,文档:https://github.com/alibaba/druid/wiki/常见问题 -->
    
<
bean 
id
=
"dataSource" 
class
=
"com.alibaba.druid.pool.DruidDataSource"
        
destroy-method
=
"close"
>
        
<!-- 数据库基本信息配置 -->
        
<
property 
name
=
"url" 
value
=
"${url}" 
/>
        
<
property 
name
=
"username" 
value
=
"${username}" 
/>
        
<
property 
name
=
"password" 
value
=
"${password}" 
/>
        
<
property 
name
=
"driverClassName" 
value
=
"${driverClassName}" 
/>
        
<
property 
name
=
"filters" 
value
=
"${filters}" 
/>
        
<!-- 最大并发连接数 -->
        
<
property 
name
=
"maxActive" 
value
=
"${maxActive}" 
/>
        
<!-- 初始化连接数量 -->
        
<
property 
name
=
"initialSize" 
value
=
"${initialSize}" 
/>
        
<!-- 配置获取连接等待超时的时间 -->
        
<
property 
name
=
"maxWait" 
value
=
"${maxWait}" 
/>
        
<!-- 最小空闲连接数 -->
        
<
property 
name
=
"minIdle" 
value
=
"${minIdle}" 
/>
        
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        
<
property 
name
=
"timeBetweenEvictionRunsMillis" 
value
=
"${timeBetweenEvictionRunsMillis}" 
/>
        
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        
<
property 
name
=
"minEvictableIdleTimeMillis" 
value
=
"${minEvictableIdleTimeMillis}" 
/>
        
<
property 
name
=
"validationQuery" 
value
=
"${validationQuery}" 
/>
        
<
property 
name
=
"testWhileIdle" 
value
=
"${testWhileIdle}" 
/>
        
<
property 
name
=
"testOnBorrow" 
value
=
"${testOnBorrow}" 
/>
        
<
property 
name
=
"testOnReturn" 
value
=
"${testOnReturn}" 
/>
        
<
property 
name
=
"maxOpenPreparedStatements" 
value
=
"${maxOpenPreparedStatements}" 
/>
        
<!-- 打开 removeAbandoned 功能 -->
        
<
property 
name
=
"removeAbandoned" 
value
=
"${removeAbandoned}" 
/>
        
<!-- 1800 秒,也就是 30 分钟 -->
        
<
property 
name
=
"removeAbandonedTimeout" 
value
=
"${removeAbandonedTimeout}" 
/>
        
<!-- 关闭 abanded 连接时输出错误日志 -->
        
<
property 
name
=
"logAbandoned" 
value
=
"${logAbandoned}" 
/>
    
</
bean
>
 
    
<!-- MyBatis相关配置 -->
    
<
bean 
id
=
"sqlSessionFactory" 
class
=
"org.mybatis.spring.SqlSessionFactoryBean"
>
        
<
property 
name
=
"configLocation" 
value
=
"classpath:context/sql-map-config.xml" 
/>
        
<
property 
name
=
"dataSource" 
ref
=
"dataSource" 
/>
    
</
bean
>
    
<
bean 
class
=
"org.mybatis.spring.mapper.MapperScannerConfigurer"
>
        
<
property 
name
=
"basePackage" 
value
=
"cn.zifangsky.mapper" 
/>
        
<
property 
name
=
"sqlSessionFactoryBeanName" 
value
=
"sqlSessionFactory" 
/>
    
</
bean
>
 
    
<
bean 
id
=
"sqlSessionTemplate" 
class
=
"org.mybatis.spring.SqlSessionTemplate"
>
        
<
constructor-arg 
index
=
"0" 
ref
=
"sqlSessionFactory" 
/>
    
</
bean
>
 
    
<!-- 事务相关配置 -->
    
<
bean 
id
=
"transactionManager"
        
class
=
"org.springframework.jdbc.datasource.DataSourceTransactionManager"
>
        
<
property 
name
=
"dataSource" 
ref
=
"dataSource" 
/>
    
</
bean
>
 
    
<
tx:annotation-driven 
transaction-manager
=
"transactionManager" 
/>
</
beans
>

注:jdbc.properties文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
url: jdbc:mysql://localhost:3306/cookie_db
driverClassName: com.mysql.jdbc.Driver
username: root
password: root
filters: stat,wall
maxActive: 100
initialSize: 10
maxWait: 60000
minIdle: 10
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 123
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
maxOpenPreparedStatements: 20
removeAbandoned: true
removeAbandonedTimeout: 1800
logAbandoned: true

(3)新建测试的DAO层的代码:

由于我这里使用的是Mybatis,因此就直接使用“mybatis-generator”插件自动生成一些基本文件了

注:关于“mybatis-generator”插件的使用想了解更多可以参考我的这篇文章:

(4)单元测试示例:

在src/test/java目录下新建TestUserTable.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
27
package 
cn.zifangsky.test.base;
 
import 
org.junit.Test;
import 
org.junit.runner.RunWith;
import 
org.springframework.beans.factory.annotation.Autowired;
import 
org.springframework.test.context.ContextConfiguration;
import 
org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
import 
cn.zifangsky.mapper.UserMapper;
import 
cn.zifangsky.model.User;
import 
junit.framework.Assert;
 
@RunWith
(SpringJUnit4ClassRunner.
class
)
@ContextConfiguration
(locations={
"classpath:/context/context.xml"
})
public 
class 
TestUserTable {
    
@Autowired
    
UserMapper userMapper;
     
    
@Test
    
public 
void 
testSelectByPrimaryKey(){
        
User user = userMapper.selectByPrimaryKey(
1
);
         
//      System.out.println(user.getName());
        
Assert.assertEquals(
"admin"
, user.getName());  
//预期值-实际值
    
}
 
}

关于这里的代码我简单解释下:

  1. @RunWith注解配置了此次测试使用的环境

  2. @ContextConfiguration注解配置了基本的Spring配置文件的路径

  3. UserMapper 是一个具体的DAO层的类,使用@Autowired注解自动注入到这个单元测试中

  4. @Test注解标注的方法被当做一个测试方法,里面的内容随意。当然,这里仅仅只是测试了根据主键查询一个实体

  5. junit.framework.Assert 这个类可以用于断言,这里就是判断从数据库中查出来的用户名是否为“admin” 。如果是,那么此次测试成功,如果不是则测试失败。如果不习惯这种写法的话还可以使用我注释掉的那样直接在控制台中打印一些数据,然后我们再手动判断

(5)运行单元测试:

关于单元测试,可以有以下几种方式来运行测试,分别是:

  1. 在标注了@Test注解的方法上鼠标右键选择:Run As –> JUnit Test ,这种方式测试的就是这一个方法

  2. 在一个单元测试的Java类上鼠标右键选择JUnit单元测试,这种方式测试的是这个类中的所有标有@Test注解的方法

  3. 在一个包或者一个目录上选择JUnit单元测试。很显然,这种方式的测试的实例更多

如果一个方法测试成功,那么在JUnit视图中是这样的:

相反,测试失败显示的视图是这样的:

本文转自 pangfc 51CTO博客,原文链接:http://blog.51cto.com/983836259/1864248,如需转载请自行联系原作者

你可能感兴趣的文章
Java springcloud B2B2C o2o多用户商城 springcloud架构(八)springboot整合mongodb
查看>>
3年工作经验的Java程序员面试经过
查看>>
Mysql 批量写入数据,对于这类性能问题,你是如何优化的
查看>>
MySQL无法启动几种常见问题小结
查看>>
阿里CTO:阿里所有技术和产品输出都将必须通过阿里云进行
查看>>
更好用的集群限流功能,Sentinel 发布 v1.4.2
查看>>
Python(生成执行文件)
查看>>
redis安装配置 - ttlsa教程系列之redis
查看>>
Linux --DHCP服务器配置;DHCP服务器中继
查看>>
IE版本多的可爱_已迁移
查看>>
eclipse查看jar包中class的中文注释乱码问题的解决
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
mariadb安装
查看>>
vue+vuex+axios+echarts画一个动态更新的中国地图
查看>>
5.8 volumetric post-processing--game programming gems5 笔记
查看>>
8086的地址空间
查看>>
Android开发动画效果被遮掉的解决方法
查看>>
Apache2.2.17源码编译安装以及配置虚拟主机
查看>>
2017年开发语言排名
查看>>