SpringBoot项目如何进行单元测试
Spring Boot 的测试类库
Spring Boot 提供了许多实用工具和注解来帮助测试应用程序,主要包括以下两个模块:
- spring-boot-test:支持测试的核心内容。
- spring-boot-test-autoconfigure:支持测试的自动化配置。
开发进行只要使用 spring-boot-starter-test 启动器就能引入这些 Spring Boot 测试模块,还能引入一些像 JUnit, AssertJ, Hamcrest 及其他一些有用的类库,具体如下所示:
- JUnit:Java 应用程序单元测试标准类库。
- Spring Test & Spring Boot Test:Spring Boot 应用程序功能集成化测试支持。
- AssertJ:一个轻量级的断言类库。
- Hamcrest:一个对象匹配器类库。
- Mockito:一个Java Mock测试框架,默认支付 1.x,可以修改为 2.x。
- JSONassert:一个用于JSON的断言库。
- JsonPath:一个JSON操作类库。
测试 Spring Boot 应用程序
添加 Maven 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
user实体类准备
public class User {
private Integer id;
private String name;
//如果作为controller的入参,必须存在空参的构造函数
public User() {
}
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
service准备
public interface UserService {
User add(User user);
User update(User user);
void delete(Integer id);
User selectByName(Integer id);
List<User> listUser();
}
//-------------------------------------
@Service
public class UserServicempl implements UserService {
private Map<Integer, User> userMap = new HashMap();
@PostConstruct
public void initUser() {
userMap.put(1, new User(1, "张三"));
userMap.put(2, new User(2, "李四"));
userMap.put(3, new User(3, "王五"));
userMap.put(4, new User(4, "刘能"));
}
@Override
public User add(User user) {
userMap.put(user.getId(), user);
return user;
}
@Override
public User update(User user) {
userMap.put(user.getId(), user);
return user;
}
@Override
public void delete(Integer id) {
userMap.remove(id);
}
@Override
public User selectByName(Integer id) {
return userMap.get(id);
}
@Override
public List<User> listUser() {
return new ArrayList(userMap.values());
}
}
controller准备
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("add")
public User add(@RequestBody User user) {
return userService.add(user);
}
@PostMapping("update")
public User update(@RequestBody User user) {
return userService.update(user);
}
@PostMapping("delete/{id}")
public void delete(@PathVariable(value = "id") Integer id) {
userService.delete(id);
}
@GetMapping("selectByName")
public User selectByName(Integer id) {
return userService.selectByName(id);
}
@GetMapping("listUser")
public List<User> listUser() {
return userService.listUser();
}
}
Spring Boot中单元测试类写在在src/test/java目录下,你可以手动创建具体测试类:
/**
* 添加@SpringBootTest注解, 指定用的是哪个启动类即可
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = WebApp.class)
public class WebSpringTest {
}
service单元测试
/**
* 添加@SpringBootTest注解, 指定用的是哪个启动类即可
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = WebApp.class)
public class WebSpringTest {
@Autowired
private UserService userService;
@Test
public void testListUser(){
System.out.println(userService.listUser());
}
}
简单的不能再简单了。
controller单元测试
上面只是针对Service层做测试,但是有时候需要对Controller层(API)做测试,这时候就得用到MockMvc了,你可以不必启动工程就能测试这些接口。
MockMvc实现了对Http请求的模拟,能够直接使用网络的形式,转换到Controller的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便。
/**
* 添加@SpringBootTest注解, 指定用的是哪个启动类即可
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = WebApp.class)
public class WebSpringTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mvc;
@Before
public void setupMockMvc() {
mvc = MockMvcBuilders.webAppContextSetup(wac).build(); //初始化MockMvc对象
}
/**
* 新增用户
*
* @throws Exception
*/
@Test
public void testAddUser() throws Exception {
String json = "{\"id\": \"1\",\"name\":\"Spring\"}";
mvc.perform(MockMvcRequestBuilders.post("/user/add")
.contentType("application/json; charset=utf-8")
.accept("application/json; charset=utf-8")
.content(json.getBytes()) //传json参数
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
}
/**
* 获取用户
*
* @throws Exception
*/
@Test
public void testGetUser() throws Exception {
mvc.perform(MockMvcRequestBuilders.get("/user/selectByName?id=1")
.contentType("application/json; charset=utf-8")
.accept("application/json; charset=utf-8")
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.id").value("1"))
.andExpect(MockMvcResultMatchers.jsonPath("$.name").value("张三"))
.andDo(MockMvcResultHandlers.print());
}
/**
* 修改用户
*
* @throws Exception
*/
@Test
public void testUpdateUser() throws Exception {
String json = "{\"id\":\"2\",\"name\":\"Spring\"}";
mvc.perform(MockMvcRequestBuilders.post("/user/update")
.contentType("application/json; charset=utf-8")
.accept("application/json; charset=utf-8")
.content(json.getBytes())//传json参数
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
}
/**
* 删除用户
*
* @throws Exception
*/
@Test
public void testDeleteUser() throws Exception {
mvc.perform(MockMvcRequestBuilders.post("/user/delete/3")
.contentType("application/json; charset=utf-8")
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
}
/**
* 获取用户列表
*
* @throws Exception
*/
@Test
public void testListUser() throws Exception {
mvc.perform(MockMvcRequestBuilders.get("/user/listUser")
.contentType("application/json; charset=utf-8")
.accept("application/json; charset=utf-8")
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
}
}
- mockMvc.perform执行一个请求
- MockMvcRequestBuilders.get(“/selectByName?id=3”)构造一个请求,Post请求就用.post方法
- contentType("application/json; charset=utf-8") 代表发送端发送的数据格式是application/json;charset=UTF-8
- accept(""application/json; charset=utf-8"") 代表客户端希望接受的数据类型为application/json;charset=UTF-8
- ResultActions.andExpect添加执行完成后的断言
- ResultActions.andExpect(MockMvcResultMatchers.status().isOk())方法看请求的状态响应码是否为200如果不是则抛异常,测试不通过
- andExpect(MockMvcResultMatchers.jsonPath(“$.name”).value("张三")) 这里jsonPath用来获取name字段比对是否为张三,不是就测试不通过
- ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息
测试类库的API
org.junit.Assert
断言,里面的方法基本都是静态方法。要使用的时候直接使用具体的方法即可。
assertSame("1", "2");
常用注解
junit的注解参考:单元测试Junit
SpringBoot test 注解参考:Spring Boot Test
标签:
SpringBoot
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律