在写SpringBoot项目时用到了单元测试功能,来测试Service和Controller很方便,简单记录一下
pom.xml 文件里面添加两个测试扩展包:
... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <scope>test</scope> </dependency> ...
创建一个User的实体类:
package com.demo.www.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 用户表
* @author AnYuan
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("users")
public class User implements Serializable {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 用户名
*/
private String name;
/**
* 手机号
*/
private String phone;
}
创建一个UserService:
package com.demo.www.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.demo.www.model.entity.User;
/**
* 用户表 服务类
* @author AnYuan
*/
public interface UserService extends IService<User> {
}
最后创建一个Controller:
package com.demo.www.controller;
import com.demo.www.model.entity.User;
import com.demo.www.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
* 用户Controller
* @author AnYuan
*/
@Slf4j
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user/{id}")
public User getUser(@PathVariable String id) {
return userService.getById(id);
}
}
接口写好之后,创建一个测试类。如过使用IDEA开发的话,点击需要测试的类,command + shift 键即可生成对应的测试类。
这里配置 @AutoConfigureMockMvc 注解自动注入 MockMvc 类进行测试。使用该注解可以不启动 tomcat 服务器,但启动Spring应用的程序,再使用mockMvc进行http请求测试
package com.demo.www.controller;
import org.hamcrest.core.StringContains;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
/**
*
* perform : 执行MockMvcRequestBuilders的请求并返回一个类型,该类型结果可以链式操作。
* MockMvcRequestBuilders请求的类型包括:get(),post(),put(),delete()。
*
* accept : 希望接收的数据类型
* header : 表明请求客户端类型
* param : 请求参数
* ...
*
* andExpect : 添加 MockMvcResultMatchers 的结果验证器。可以判断http状态码和返回json是否为包含期望值
* andDo: 添加 MockMvcResultHandlers 的结果处理器,可以打印返回的内容
*/
@Test
public void getUser() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/user/1")
.accept(MediaType.APPLICATION_JSON)
.header("X-Client", "app")
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().string(StringContains.containsString("age")))
.andDo(MockMvcResultHandlers.print())
.andReturn();
}
}
最后执行该测试方法,正常情况下控制台输出:

Url不存在异常:

返回的数据里面没有包含期望的字符串异常:

以上就是SpringBoot里简单测试Controller,除了使用MockMvc,还可以注入 TestRestTemplate 来使用http的请求测试。
如果要测试Service层,可以直接注入Servic服务,在Test类的方法里面调用Service的方法。
Spring官方测试用例:https://spring.io/guides/gs/testing-web/
