Skip to content

Commit 07653c8

Browse files
committedMay 2, 2018
Spring Boot中编写单元测试
1 parent 2b182c4 commit 07653c8

File tree

15 files changed

+600
-0
lines changed

15 files changed

+600
-0
lines changed
 

‎19.Spring-Boot-Testing/pom.xml

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<groupId>demo.springboot</groupId>
7+
<artifactId>Spring-Boot-Testing</artifactId>
8+
<version>0.0.1-SNAPSHOT</version>
9+
<packaging>jar</packaging>
10+
11+
<name>test</name>
12+
<description>Demo project for Spring Boot test</description>
13+
14+
<parent>
15+
<groupId>org.springframework.boot</groupId>
16+
<artifactId>spring-boot-starter-parent</artifactId>
17+
<version>1.5.9.RELEASE</version>
18+
<relativePath/> <!-- lookup parent from repository -->
19+
</parent>
20+
21+
<properties>
22+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
23+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
24+
<java.version>1.7</java.version>
25+
</properties>
26+
27+
<dependencies>
28+
<dependency>
29+
<groupId>org.springframework.boot</groupId>
30+
<artifactId>spring-boot-starter-web</artifactId>
31+
</dependency>
32+
33+
<dependency>
34+
<groupId>org.springframework.boot</groupId>
35+
<artifactId>spring-boot-starter-test</artifactId>
36+
<scope>test</scope>
37+
</dependency>
38+
39+
<!--mybatis-->
40+
<dependency>
41+
<groupId>org.mybatis.spring.boot</groupId>
42+
<artifactId>mybatis-spring-boot-starter</artifactId>
43+
<version>1.3.1</version>
44+
</dependency>
45+
<!--通用mapper-->
46+
<dependency>
47+
<groupId>tk.mybatis</groupId>
48+
<artifactId>mapper-spring-boot-starter</artifactId>
49+
<version>1.1.5</version>
50+
</dependency>
51+
<!--pagehelper 分页插件-->
52+
<dependency>
53+
<groupId>com.github.pagehelper</groupId>
54+
<artifactId>pagehelper-spring-boot-starter</artifactId>
55+
<version>1.2.3</version>
56+
</dependency>
57+
58+
<dependency>
59+
<groupId>com.oracle</groupId>
60+
<artifactId>ojdbc6</artifactId>
61+
<version>6.0</version>
62+
</dependency>
63+
<dependency>
64+
<groupId>com.alibaba</groupId>
65+
<artifactId>druid-spring-boot-starter</artifactId>
66+
<version>1.1.6</version>
67+
</dependency>
68+
</dependencies>
69+
70+
<build>
71+
<plugins>
72+
<plugin>
73+
<groupId>org.springframework.boot</groupId>
74+
<artifactId>spring-boot-maven-plugin</artifactId>
75+
</plugin>
76+
</plugins>
77+
</build>
78+
79+
80+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package demo.springboot.test;
2+
3+
import org.mybatis.spring.annotation.MapperScan;
4+
import org.springframework.boot.SpringApplication;
5+
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
import org.springframework.transaction.annotation.EnableTransactionManagement;
7+
8+
@SpringBootApplication
9+
@EnableTransactionManagement
10+
@MapperScan("demo.springboot.test.mapper")
11+
public class TestApplication {
12+
13+
public static void main(String[] args) {
14+
SpringApplication.run(TestApplication.class, args);
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package demo.springboot.test.config;
2+
3+
import tk.mybatis.mapper.common.Mapper;
4+
import tk.mybatis.mapper.common.MySqlMapper;
5+
6+
public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T> {
7+
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package demo.springboot.test.controller;
2+
3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.springframework.web.bind.annotation.GetMapping;
5+
import org.springframework.web.bind.annotation.PathVariable;
6+
import org.springframework.web.bind.annotation.PostMapping;
7+
import org.springframework.web.bind.annotation.RequestBody;
8+
import org.springframework.web.bind.annotation.RestController;
9+
10+
import demo.springboot.test.domain.User;
11+
import demo.springboot.test.service.UserService;
12+
13+
@RestController
14+
public class UserController {
15+
16+
@Autowired
17+
UserService userService;
18+
19+
@GetMapping("user/{userName}")
20+
public User getUserByName(@PathVariable(value = "userName") String userName) {
21+
return this.userService.findByName(userName);
22+
}
23+
24+
@PostMapping("user/save")
25+
public void saveUser(@RequestBody User user) {
26+
this.userService.saveUser(user);
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package demo.springboot.test.domain;
2+
3+
import java.util.Date;
4+
5+
import javax.persistence.Column;
6+
import javax.persistence.Id;
7+
import javax.persistence.Table;
8+
9+
@Table(name = "T_USER")
10+
public class User {
11+
@Id
12+
@Column(name = "USER_ID")
13+
private Long id;
14+
15+
@Column(name = "USERNAME")
16+
private String username;
17+
18+
@Column(name = "PASSWORD")
19+
private String passwd;
20+
21+
@Column(name = "CRATE_TIME")
22+
private Date createTime;
23+
24+
@Column(name = "STATUS")
25+
private String status;
26+
27+
/**
28+
* @return ID
29+
*/
30+
public Long getId() {
31+
return id;
32+
}
33+
34+
/**
35+
* @param id
36+
*/
37+
public void setId(Long id) {
38+
this.id = id;
39+
}
40+
41+
/**
42+
* @return USERNAME
43+
*/
44+
public String getUsername() {
45+
return username;
46+
}
47+
48+
/**
49+
* @param username
50+
*/
51+
public void setUsername(String username) {
52+
this.username = username == null ? null : username.trim();
53+
}
54+
55+
/**
56+
* @return PASSWD
57+
*/
58+
public String getPasswd() {
59+
return passwd;
60+
}
61+
62+
/**
63+
* @param passwd
64+
*/
65+
public void setPasswd(String passwd) {
66+
this.passwd = passwd == null ? null : passwd.trim();
67+
}
68+
69+
/**
70+
* @return CREATE_TIME
71+
*/
72+
public Date getCreateTime() {
73+
return createTime;
74+
}
75+
76+
/**
77+
* @param createTime
78+
*/
79+
public void setCreateTime(Date createTime) {
80+
this.createTime = createTime;
81+
}
82+
83+
/**
84+
* @return STATUS
85+
*/
86+
public String getStatus() {
87+
return status;
88+
}
89+
90+
/**
91+
* @param status
92+
*/
93+
public void setStatus(String status) {
94+
this.status = status == null ? null : status.trim();
95+
}
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package demo.springboot.test.mapper;
2+
3+
import org.apache.ibatis.annotations.Param;
4+
import org.apache.ibatis.annotations.Select;
5+
6+
public interface SeqenceMapper {
7+
@Select("select ${seqName}.nextval from dual")
8+
Long getSequence(@Param("seqName") String seqName);
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package demo.springboot.test.mapper;
2+
3+
import demo.springboot.test.config.MyMapper;
4+
import demo.springboot.test.domain.User;
5+
6+
public interface UserMapper extends MyMapper<User> {
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package demo.springboot.test.service;
2+
3+
import java.util.List;
4+
5+
import org.apache.ibatis.annotations.Param;
6+
import org.springframework.stereotype.Service;
7+
8+
@Service
9+
public interface IService<T> {
10+
11+
Long getSequence(@Param("seqName") String seqName);
12+
13+
List<T> selectAll();
14+
15+
T selectByKey(Object key);
16+
17+
int save(T entity);
18+
19+
int delete(Object key);
20+
21+
int updateAll(T entity);
22+
23+
int updateNotNull(T entity);
24+
25+
List<T> selectByExample(Object example);
26+
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package demo.springboot.test.service;
2+
3+
import demo.springboot.test.domain.User;
4+
5+
public interface UserService extends IService<User>{
6+
User findByName(String userName);
7+
8+
void saveUser(User user);
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package demo.springboot.test.service.impl;
2+
3+
import java.util.List;
4+
5+
import org.apache.ibatis.annotations.Param;
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
8+
import demo.springboot.test.mapper.SeqenceMapper;
9+
import demo.springboot.test.service.IService;
10+
import tk.mybatis.mapper.common.Mapper;
11+
12+
public abstract class BaseService<T> implements IService<T> {
13+
14+
@Autowired
15+
protected Mapper<T> mapper;
16+
@Autowired
17+
protected SeqenceMapper seqenceMapper;
18+
19+
public Mapper<T> getMapper() {
20+
return mapper;
21+
}
22+
@Override
23+
public Long getSequence(@Param("seqName") String seqName){
24+
return seqenceMapper.getSequence(seqName);
25+
}
26+
27+
@Override
28+
public List<T> selectAll() {
29+
//说明:查询所有数据
30+
return mapper.selectAll();
31+
}
32+
33+
@Override
34+
public T selectByKey(Object key) {
35+
//说明:根据主键字段进行查询,方法参数必须包含完整的主键属性,查询条件使用等号
36+
return mapper.selectByPrimaryKey(key);
37+
}
38+
39+
@Override
40+
public int save(T entity) {
41+
//说明:保存一个实体,null的属性也会保存,不会使用数据库默认值
42+
return mapper.insert(entity);
43+
}
44+
45+
@Override
46+
public int delete(Object key) {
47+
//说明:根据主键字段进行删除,方法参数必须包含完整的主键属性
48+
return mapper.deleteByPrimaryKey(key);
49+
}
50+
51+
@Override
52+
public int updateAll(T entity) {
53+
//说明:根据主键更新实体全部字段,null值会被更新
54+
return mapper.updateByPrimaryKey(entity);
55+
}
56+
57+
@Override
58+
public int updateNotNull(T entity) {
59+
//根据主键更新属性不为null的值
60+
return mapper.updateByPrimaryKeySelective(entity);
61+
}
62+
63+
@Override
64+
public List<T> selectByExample(Object example) {
65+
//说明:根据Example条件进行查询
66+
//重点:这个查询支持通过Example类指定查询列,通过selectProperties方法指定查询列
67+
return mapper.selectByExample(example);
68+
}
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package demo.springboot.test.service.impl;
2+
3+
import java.util.Date;
4+
import java.util.List;
5+
6+
import org.springframework.stereotype.Repository;
7+
8+
import demo.springboot.test.domain.User;
9+
import demo.springboot.test.service.UserService;
10+
import tk.mybatis.mapper.entity.Example;
11+
12+
@Repository("userService")
13+
public class UserServiceImpl extends BaseService<User> implements UserService {
14+
15+
@Override
16+
public User findByName(String userName) {
17+
Example example = new Example(User.class);
18+
example.createCriteria().andCondition("username=", userName);
19+
List<User> userList = this.selectByExample(example);
20+
if (userList.size() != 0)
21+
return userList.get(0);
22+
else
23+
return null;
24+
}
25+
26+
@Override
27+
public void saveUser(User user) {
28+
user.setId(this.getSequence("seq_user"));
29+
user.setCreateTime(new Date());
30+
this.save(user);
31+
}
32+
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
server:
2+
context-path: /web
3+
4+
spring:
5+
datasource:
6+
druid:
7+
# 数据库访问配置, 使用druid数据源
8+
type: com.alibaba.druid.pool.DruidDataSource
9+
driver-class-name: oracle.jdbc.driver.OracleDriver
10+
url: jdbc:oracle:thin:@localhost:1521:ORCL
11+
username: test
12+
password: 123456
13+
# 连接池配置
14+
initial-size: 5
15+
min-idle: 5
16+
max-active: 20
17+
# 连接等待超时时间
18+
max-wait: 30000
19+
# 配置检测可以关闭的空闲连接间隔时间
20+
time-between-eviction-runs-millis: 60000
21+
# 配置连接在池中的最小生存时间
22+
min-evictable-idle-time-millis: 300000
23+
validation-query: select '1' from dual
24+
test-while-idle: true
25+
test-on-borrow: false
26+
test-on-return: false
27+
# 打开PSCache,并且指定每个连接上PSCache的大小
28+
pool-prepared-statements: true
29+
max-open-prepared-statements: 20
30+
max-pool-prepared-statement-per-connection-size: 20
31+
# 配置监控统计拦截的filters, 去掉后监控界面sql无法统计, 'wall'用于防火墙
32+
filters: stat,wall
33+
# Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔
34+
aop-patterns: demo.springboot.test.servie.*
35+
36+
37+
# WebStatFilter配置
38+
web-stat-filter:
39+
enabled: true
40+
# 添加过滤规则
41+
url-pattern: /*
42+
# 忽略过滤的格式
43+
exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
44+
45+
# StatViewServlet配置
46+
stat-view-servlet:
47+
enabled: true
48+
# 访问路径为/druid时,跳转到StatViewServlet
49+
url-pattern: /druid/*
50+
# 是否能够重置数据
51+
reset-enable: false
52+
# 需要账号密码才能访问控制台
53+
login-username: druid
54+
login-password: druid123
55+
# IP白名单
56+
# allow: 127.0.0.1
57+
# IP黑名单(共同存在时,deny优先于allow)
58+
# deny: 192.168.1.218
59+
60+
# 配置StatFilter
61+
filter:
62+
stat:
63+
log-slow-sql: true
64+
65+
mybatis:
66+
config-location: classpath:config/mybatis-config.xml
67+
# type-aliases扫描路径
68+
type-aliases-package: demo.springboot.test.domain
69+
# mapper xml实现扫描路径
70+
mapper-locations: classpath:mapper/*.xml
71+
property:
72+
order: BEFORE
73+
74+
75+
#mappers 多个接口时逗号隔开
76+
mapper:
77+
mappers: demo.springboot.test.config.MyMapper
78+
not-empty: false
79+
identity: oracle
80+
81+
#pagehelper
82+
pagehelper:
83+
helperDialect: oracle
84+
reasonable: true
85+
supportMethodsArguments: true
86+
params: count=countSql
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE configuration
3+
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
4+
"http://mybatis.org/dtd/mybatis-3-config.dtd">
5+
<configuration>
6+
<settings>
7+
<!--解决插入null的时候报错问题-->
8+
<setting name="jdbcTypeForNull" value="NULL"/>
9+
</settings>
10+
</configuration>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
-- ----------------------------
2+
-- Table structure for T_USER
3+
-- ----------------------------
4+
CREATE TABLE T_USER (
5+
ID NUMBER NOT NULL ,
6+
USERNAME VARCHAR2(20 BYTE) NOT NULL ,
7+
PASSWD VARCHAR2(128 BYTE) NOT NULL ,
8+
CREATE_TIME DATE NULL ,
9+
STATUS CHAR(1 BYTE) NOT NULL
10+
);
11+
COMMENT ON COLUMN T_USER.USERNAME IS '用户名';
12+
COMMENT ON COLUMN T_USER.PASSWD IS '密码';
13+
COMMENT ON COLUMN T_USER.CREATE_TIME IS '创建时间';
14+
COMMENT ON COLUMN T_USER.STATUS IS '是否有效 1:有效 0:锁定';
15+
-- ----------------------------
16+
-- Records of T_USER
17+
-- ----------------------------
18+
INSERT INTO T_USER VALUES ('2', 'tester', '243e29429b340192700677d48c09d992', TO_DATE('2017-12-11 17:20:21', 'YYYY-MM-DD HH24:MI:SS'), '1');
19+
INSERT INTO T_USER VALUES ('1', 'mrbird', '42ee25d1e43e9f57119a00d0a39e5250', TO_DATE('2017-12-11 10:52:48', 'YYYY-MM-DD HH24:MI:SS'), '1');
20+
21+
create sequence seq_user start with 1 INCREMENT by 1;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package demo.springboot.test;
2+
3+
import javax.servlet.http.Cookie;
4+
5+
import org.junit.Before;
6+
import org.junit.Test;
7+
import org.junit.runner.RunWith;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.boot.test.context.SpringBootTest;
10+
import org.springframework.http.MediaType;
11+
import org.springframework.mock.web.MockHttpSession;
12+
import org.springframework.test.context.junit4.SpringRunner;
13+
import org.springframework.test.web.servlet.MockMvc;
14+
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
15+
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
16+
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
17+
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
18+
import org.springframework.transaction.annotation.Transactional;
19+
import org.springframework.web.context.WebApplicationContext;
20+
21+
import com.fasterxml.jackson.databind.ObjectMapper;
22+
import com.jayway.jsonpath.JsonPath;
23+
24+
import demo.springboot.test.domain.User;
25+
26+
@RunWith(SpringRunner.class)
27+
@SpringBootTest
28+
public class UserControllerTest {
29+
30+
private MockMvc mockMvc;
31+
private MockHttpSession session;
32+
33+
@Autowired
34+
private WebApplicationContext wac;
35+
36+
@Autowired
37+
ObjectMapper mapper;
38+
39+
40+
@Before
41+
public void setupMockMvc(){
42+
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
43+
session = new MockHttpSession();
44+
User user =new User();
45+
user.setUsername("Dopa");
46+
user.setPasswd("ac3af72d9f95161a502fd326865c2f15");
47+
session.setAttribute("user",user);
48+
}
49+
50+
@Test
51+
@Transactional
52+
public void test() throws Exception {
53+
// mockMvc.perform(
54+
// MockMvcRequestBuilders.get("/user/{userName}", "scott")
55+
// .contentType(MediaType.APPLICATION_JSON_UTF8))
56+
// .andExpect(MockMvcResultMatchers.status().isOk())
57+
// .andExpect(MockMvcResultMatchers.jsonPath("$.username").value("scott"))
58+
// .andDo(MockMvcResultHandlers.print());
59+
60+
// String jsonStr = "{\"username\":\"Dopa\",\"passwd\":\"ac3af72d9f95161a502fd326865c2f15\",\"status\":\"1\"}";
61+
62+
User user = new User();
63+
user.setUsername("Dopa");
64+
user.setPasswd("ac3af72d9f95161a502fd326865c2f15");
65+
user.setStatus("1");
66+
67+
String userJson = mapper.writeValueAsString(user);
68+
69+
70+
// mockMvc.perform(MockMvcRequestBuilders.post("/user/save").content(jsonStr.getBytes()));
71+
72+
mockMvc.perform(
73+
MockMvcRequestBuilders.post("/user/save")
74+
.contentType(MediaType.APPLICATION_JSON_UTF8)
75+
.content(userJson.getBytes()))
76+
.andExpect(MockMvcResultMatchers.status().isOk())
77+
.andDo(MockMvcResultHandlers.print());
78+
79+
// mockMvc.perform(MockMvcRequestBuilders.get("/hello?name={name}","mrbird"));
80+
// mockMvc.perform(MockMvcRequestBuilders.post("/user/{id}", 1));
81+
// mockMvc.perform(MockMvcRequestBuilders.fileUpload("/fileupload").file("file", "文件内容".getBytes("utf-8")));
82+
// mockMvc.perform(MockMvcRequestBuilders.get("/hello").param("message", "hello"));
83+
// mockMvc.perform(MockMvcRequestBuilders.get("/hobby/save").param("hobby", "sleep", "eat"));
84+
85+
// MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
86+
// params.add("name", "mrbird");
87+
// params.add("hobby", "sleep");
88+
// params.add("hobby", "eat");
89+
// mockMvc.perform(MockMvcRequestBuilders.get("/hobby/save").params(params));
90+
// mockMvc.perform(MockMvcRequestBuilders.get("/index").sessionAttr(name, value));
91+
// mockMvc.perform(MockMvcRequestBuilders.get("/index").cookie(new Cookie(name, value)));
92+
// mockMvc.perform(MockMvcRequestBuilders.get("/index").contentType(MediaType.APPLICATION_JSON_UTF8));
93+
// mockMvc.perform(MockMvcRequestBuilders.get("/user/{id}", 1).accept(MediaType.APPLICATION_JSON));
94+
// mockMvc.perform(MockMvcRequestBuilders.get("/user/{id}", 1).header(name, values));
95+
96+
// mockMvc.perform(MockMvcRequestBuilders.get("/index"))
97+
// .andDo(MockMvcResultHandlers.print());
98+
99+
100+
}
101+
}

0 commit comments

Comments
 (0)
Please sign in to comment.