大纲
关于单元测试,我们一直以来用的很少,最近想研究一下,在团队中推广,看看是否有推广价值。
在用Springboot或者SSM的开发过程中,我每次测试程序时,都是在程序中打断点,然后启动整个程序进行调试,这种模式,感觉很麻烦。有的程序启动一次加载的内容较多,需要启动很久。
最近学习了一下Junit单元测试,感觉简单了很多。
1. 测试场景:
下面介绍一下我们常用的几种测试场景。
场景一:目前最常用的还是SpringBoot+Mybatis集成框架,我们在开发时,刚刚写完一个map层的sql文件,想测试一下,原来的方法是从controller层,到service层都需要把程序写完,然后启动程序,用浏览器访问controller层的方法进行大断点进行调试。这样的确很啰嗦!!!
场景二:在测试controller层的方法时,我们需要浏览器的配合,有时候,浏览器的参数很多时,也不利用测试。
下面分别介绍一下,这两种测试场景,在用了Junit单元测试后,是否会变得简单呢
2. 添加依赖与配置
下面的配置文件,集成了web启动器、mybatis启动器的集成、及单元测试的启动器集成。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
3. ApplicationContext测试实例
3.1. 集成mybatis及mybatis-plus
用到mybatis必然要用到他的增加软件mybatis-plus,这一章节详细介绍Springboot怎么集成这两种框架。
3.1.1 pom文件增加对mybatis及mybatis-plus的集成
<!--集成mybatis start-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- druid 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<!-- mybatis plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<!--集成mybatis end-->
从配置文件可以看出,我们使用了druid 数据库连接池,这是阿里巴巴提供的,内置web监控界面,可以监控数据库访问情况及语句执行信息。
3.1.2 配置文件增加mybatis及mybatis-plus相关参数配置
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: classpath:mapping/*Mapper.xml
type-aliases-package: com.ieslab.powergrid.entity
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
global-config:
# 关闭MP3.0自带的banner
banner: false
db-config:
# 默认数据库表下划线命名
table-underline: true
配置文件中的用户名和密码、数据库名等需要根据实际情况而设置;
3.1.1.3 增加分页插件配置类
新建MybatisPlusConfig.java类
package com.ieslab.powergrid.demosvr.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
//实现分页插件
@EnableTransactionManagement(proxyTargetClass = true)
@Configuration
@MapperScan("mapper")
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
这个类主要就是让分页插件功能生效。
这样mybatis和mybatis-plus就集成完毕了,后续会编写代码进行测试
4.集成日志框架,简化日志编码
4.1 pom文件增加日志相关依赖
<!-- set/get方法免写,需要安装idea的插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
4.2 使用注解进行日志使用
在测试目录创建测试类DemosvrApplicationTests.java,代码如下:
package com.ieslab.powergrid.demosvr;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
@Slf4j
class DemosvrApplicationTests {
@Test
void contextLoads() {
log.info("contextLoads is running");
}
}
代码中在类是前面添加:@Slf4j 注解后,就可以在本类中直接用log.info 进行打印日志。
5.demo实例编写
5.1 编写mapper接口及实现文件
5.1.1 首先创建Person.java类:
package com.ieslab.powergrid.demosvr.entity;
import lombok.Data;
import org.springframework.stereotype.Component;
@Data
public class Person {
int id;
String lastName;
String firstName;
String address ;
String city;
public Person() {
}
public Person(String lastName, String firstName, String address, String city) {
this.lastName = lastName;
this.firstName = firstName;
this.address = address;
this.city = city;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", lastName='" + lastName + '\'' +
", firstName='" + firstName + '\'' +
", address='" + address + '\'' +
", city='" + city + '\'' +
'}';
}
}
5.1.2 编写PersonMapper.java接口类:
package com.ieslab.powergrid.demosvr.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ieslab.powergrid.demosvr.entity.Person;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
import java.util.Map;
@Mapper
public interface PersonMapper extends BaseMapper<Person> {
//根据过滤条件获取用户
List<Person> getPersonByFilter(Map<String, String> param);
}
5.1.3 在resources目录下创建mapper目录,并在此目录下创建PersonMapper.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ieslab.powergrid.demosvr.mapper.PersonMapper">
<select id="getPersonByFilter" resultType="com.ieslab.powergrid.demosvr.entity.Person">
select * from person
<where>
<if test="id != null">
id=#{id}
</if>
<if test="name != null and name != ''">
and last_name like CONCAT('%','${name}','%' )
</if>
</where>
</select>
</mapper>
关于mapper文件的写法,有几个重点需要注意:
- namespace=“com.ieslab.powergrid.demosvr.mapper.PersonMapper” 这是一定要写对应的接口类
- resultType=“com.ieslab.powergrid.demosvr.entity.Person” 这是返回的数据类型,一定要正确,还有别的写法,可以查阅相关资料学习。
- 对于sql语句,尽量要用标签的方法编写,比如: 标签,ognl的写法一定不能缺少。
5.1.4 创建数据库、表
mysql数据库的安装,请查阅:https://blog.csdn.net/houpeibin2012/article/details/104224168
创建数据库:springboot
创建person表,建表语句如下:
建表语句:
CREATE TABLE Person
(
id int,
Last_Name varchar(255),
First_Name varchar(255),
Address varchar(255),
City varchar(255)
)
注意:表字段和person类的变量要对应,java实体类中采取驼峰方式进行命名时,数据要用下划线方式进行分开,比如:java类中lastName 变量对应数据库表中last_name的名称。
这样数据库表、数据库层的代码已经编写完毕。
5.2 编写service类
编写业务层代码,创建PersonService.java类:
package com.ieslab.powergrid.demosvr.service;
import com.ieslab.powergrid.demosvr.entity.Person;
import com.ieslab.powergrid.demosvr.mapper.PersonMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/** <p>Title: PersonService </p>
* <p>Description: 用户业务类,测试demo使用</p>
*
* @author houpeibin
* @date 2020-2-20 下午7:15:30
* @version V1.0
*/
@Service
public class PersonService {
@Autowired
PersonMapper personMapper;
/**
* 获取所有用户
* @return
*/
public List<Person> getPersons(){
return personMapper.selectList(null);
}
/**
* 插入用户
* @param person 用户信息类
* @return 插入几条数据
*/
public int insertPersons(Person person){
return personMapper.insert(person);
}
}
6.集成Junit单元测试
6.1 编写测试代码
在PersonService.java类上点击右键,选择Generate,再选择Test…
弹出框中的测试类,一般不用改名,他就是service类加了后缀Test,方便找。
在Springboot中使用Junit进行单元测试的方法很简单,只需要在编写的单元测试类上添加两个注解:@RunWith(SpringRunner.class)和@SpringBootTest。
开发这个测试类,编写如下代码:
package com.ieslab.powergrid.demosvr.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ieslab.powergrid.demosvr.entity.Person;
import com.ieslab.powergrid.demosvr.mapper.PersonMapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** <p>Title: PersonServiceTest </p>
* <p>Description: PersonService测试类</p>
*
* @author houpeibin
* @date 2020-2-20 下午7:15:30
* @version V1.0
*/
@SpringBootTest
@Slf4j
class PersonServiceTest {
@Autowired
PersonService personService;
@Autowired
PersonMapper personMapper;
/**
* 插入用户
*/
@Test
void insertPersons(){
for (int i=0;i<10;++i){
Person person = new Person();
person.setId(i);
person.setFirstName("zhang");
person.setLastName(""+i);
person.setCity("jinan");
person.setAddress("huayang");
log.info("insert person:" + personService.insertPersons(person));
}
}
/**
* 根据id获取用户
*/
@Test
void getPersonsById(){
Map<String, String> mapParam = new HashMap<>();
mapParam.put("id","1");
List<Person> persons = personMapper.getPersonByFilter(mapParam);
log.info(persons.toString());
}
/**
* 根据名称模糊查询
*/
@Test
void getPersonsByName(){
Map<String, String> mapParam = new HashMap<>();
mapParam.put("name","3");
List<Person> persons = personMapper.getPersonByFilter(mapParam);
log.info(persons.toString());
}
/**
* 分页查询测试
*/
@Test
void getPersonsPage(){
IPage<Person> page = new Page<Person>(0,5);
IPage<Map<String, Object>> pageData = personMapper.selectMapsPage(page,null);
List list = pageData.getRecords();
for (Object obj:list){
System.out.println(obj.toString());
}
}
}
上面写了四个测试方法,一个是插入10条数据,一个是按照id查询,一个是按照name模糊查询,最后一个是分页查询,下面我们来运行测试用例。
6.2 使用单元测试进行测试
查看执行结果:
用类似的方法,去执行其他方法进行测试。
怎么样,这样测试是不是很方便,Springboot集成mybatis也就成功了,简单吧,后续你只要好好学习sql的写法就可以了。
7.1 Controller层测试实例
7.1.1 pom文件增加对web启动器的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
7.1.2 创建类PersonController.java
package com.ieslab.powergrid.demosvr.controller;
import com.ieslab.powergrid.demosvr.entity.Person;
import com.ieslab.powergrid.demosvr.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** <p>Title: PersonService </p>
* <p>Description: 用户rest接口类,测试demo使用</p>
*
* @author houpeibin
* @date 2020-2-20 下午7:15:30
* @version V1.0
*/
@RestController
@RequestMapping("/person")
public class PersonController {
@Autowired
PersonService personService;
/**
* 获取所有用户
* @return
*/
@RequestMapping("/getPersons")
public List<Person> getPersons(String id){
Map map = new HashMap<>();
map.put("id", id);
return personService.getPersons(map);
}
}
8 编写测试类PersonControllerTest.java
package com.ieslab.powergrid.demosvr.controller;
import com.ieslab.powergrid.demosvr.entity.Person;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
@Slf4j
class PersonControllerTest {
@Autowired
PersonController personController;
/**
* 根据id获取用户
*/
@Test
void getPersonsById(){
log.info(personController.getPersons("4").toString());
}
}
启动本测试类进行测试,查看日志是否打印成功。