SpringBoot - Mock框架
1、为什么要用Mock
- 团队可以并行工作:有了Mock,前后端人员只需要定义好接口文档就可以开始并行工作,互不影响,只在最后的联调阶段往来密切;后端与后端之间如果有接口耦合,也同样能被Mock解决;测试过程中如果遇到依赖接口没有准备好,同样可以借助Mock;不会出现一个团队等待另一个团队的情况。这样的话,开发自测阶段就可以及早开展,从而发现缺陷的时机也提前了,有利于整个产品质量以及进度的保证;
- 开启TDD模式,即测试驱动开发:单元测试是TDD实现的基石,而TDD经常会碰到协同模块尚未开发完成的情况,但是有了mock,这些一切都不是问题。当接口定义好后,测试人员就可以创建一个Mock,把接口添加到自动化测试环境,提前创建测试;
- 可以模拟那些无法访问的资源:比如说,你需要调用一个“墙”外的资源来方便自己调试,就可以自己Mock一个;
- 隔离系统:假如我们需要调用一个post请求,为了获得某个响应,来看当前系统是否能正确处理返回的“响应”,但是这个post请求会造成数据库中数据的污染,那么就可以充分利用Mock,构造一个虚拟的post请求,我们给他指定返回就好了;
- 可以用来演示:假如我们需要创建一个演示程序,并且做了简单的UI,那么在完全没有开发后端服务的情况下,也可以进行演示。说到演示了,假如你已经做好了一个系统,并且需要给客户进行演示,但是里面有些真实数据并不想让用户看到,那么同样,你可以用Mock接口把这些敏感信息接口全部替换;
- 测试覆盖度:假如有一个接口,有100个不同类型的返回,我们需要测试它在不同返回下,系统是否能够正常响应,但是有些返回在正常情况下基本不会发生,难道你要千方百计地给系统做各种手脚让他返回以便测试吗?比如,我们需要测试在当接口发生500错误的时候,app是否崩溃,别告诉我你一定要给服务端代码做些手脚让他返回500 。。。而使用mock,这一切就都好办了,想要什么返回就模拟什么返回,再也不用担心测试覆盖度了。
2、Mock的优缺点
- 不要过度使用mock。测试用例中,掌握好使用mock的度。在涉及到网络访问、数据库读写、操作系统交互等系统级调用,并且调用结果对SUT的处理逻辑有显著影响时,优先使用mock。
2.1、优点
- 提高测试的覆盖率;
- 提高测试的可用性;
- 提高测试效率。
2.2、缺点
- 无法完全模拟真实行为;
- 用例维护成本高;
- 用例实现成本高。
3、Mock的使用场景
4、Mock的定义
mock
是在测试过程中,对于一些不容易构造/获取的对象,创建一个mock
对象来模拟对象的行为。比如说你需要调用B服务,可是B服务还没有开发完成,那么你就可以将调用B服务的那部分给Mock掉,并编写你想要的返回结果。Mock
有很多的实现框架,例如Mockito
、EasyMock
、Jmockit
、PowerMock
、Spock
等等,SpringBoot
默认的Mock
框架是Mockito
,和junit
一样,只需要依赖spring-boot-starter-test
就可以了。
5、常用的Mock框架对比
6、Mockito
- Mockito是mocking框架,它让你用简洁的API做测试。而且Mockito简单易学,它可读性强和验证语法简洁;
- Mockito是GitHub上使用最广泛的Mock框架,并与JUnit结合使用;
- Mockito框架可以创建和配置mock对象;
- 使用Mockito简化了具有外部依赖的类的测试开发。
6.1、初始化
@RunWith(MockitoJUnitRunner.class)
public class MockitControllerTest {
private static final Logger LOGGER = LoggerFactory.getLogger(MockitController.class);
private MockMvc mvc;
private Gson gson;
@InjectMocks
MockitController mockitController;
@Before
public void setUp() {
gson = new Gson();
mvc = MockMvcBuilders.standaloneSetup(mockitController).build();
}
}
6.2、模拟post请求
@Test
public void should_return_true_when_input_valid_param() throws Exception{
User user = new User();
user.setId("12323123");
user.setName("123123123");
//perform,执行一个RequestBuilders请求,会自动执行SpringMVC的流程并映射到相应的控制器执行处理
mvc.perform(MockMvcRequestBuilders
// 模拟发个post请求
.post("/mockit/getUser")
// 接受参数
.accept(MediaType.APPLICATION_JSON)
// 请求类型
.contentType(MediaType.APPLICATION_JSON)
// 填充内容
.content(gson.toJson(user)))
// 期待的结果状态值 200
.andExpect(status().isOk())
// 添加ResultHandler结果处理器,比如调试时 打印结果(print方法)到控制台
.andDo(MockMvcResultHandlers.print());
}
7、常用API
7.1、常用期望
//使用jsonPaht验证返回的json中code、message字段的返回值
.andExpect(MockMvcResultMatchers.jsonPath("$.code").value("00000"))
.andExpect(MockMvcResultMatchers.jsonPath("$.message").value("成功"))
//body属性不为空
.andExpect(MockMvcResultMatchers.jsonPath("$.body").isNotEmpty())
// 期望的返回结果集合有2个元素 , $: 返回结果
.andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(2));
7.2、常用的RequestBuilder/MockMvcRequestBuilders
//根据uri模板和uri变量值得到一个GET请求方式的MockHttpServletRequestBuilder;
MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables)
//同get类似,但是是POST方法;
MockHttpServletRequestBuilder post(String urlTemplate, Object... urlVariables)
//同get类似,但是是PUT方法;
MockHttpServletRequestBuilder put(String urlTemplate, Object... urlVariables)
//同get类似,但是是DELETE方法;
MockHttpServletRequestBuilder delete(String urlTemplate, Object... urlVariables)
//同get类似,但是是OPTIONS方法;
MockHttpServletRequestBuilder options(String urlTemplate, Object... urlVariables)
//提供自己的Http请求方法及uri模板和uri变量,如上API都是委托给这个API;
MockHttpServletRequestBuilder request(HttpMethod httpMethod, String urlTemplate, Object... urlVariables)
//提供文件上传方式的请求,得到MockMultipartHttpServletRequestBuilder;
MockMultipartHttpServletRequestBuilder fileUpload(String urlTemplate, Object... urlVariables)
//创建一个从启动异步处理的请求的MvcResult进行异步分派的RequestBuilder;
RequestBuilder asyncDispatch(final MvcResult mvcResult)
7.3、常用的MockHttpServletRequestBuilder
//:添加头信息;
MockHttpServletRequestBuilder header(String name, Object... values)/MockHttpServletRequestBuilder headers(HttpHeaders httpHeaders)
//:指定请求的contentType头信息;
MockHttpServletRequestBuilder contentType(MediaType mediaType)
//:指定请求的Accept头信息;
MockHttpServletRequestBuilder accept(MediaType... mediaTypes)/MockHttpServletRequestBuilder accept(String... mediaTypes)
//:指定请求Body体内容;
MockHttpServletRequestBuilder content(byte[] content)/MockHttpServletRequestBuilder content(String content)
//:请求传入参数
MockHttpServletRequestBuilder param(String name,String... values)
//:指定请求的Cookie;
MockHttpServletRequestBuilder cookie(Cookie... cookies)
//:指定请求的Locale;
MockHttpServletRequestBuilder locale(Locale locale)
//:指定请求字符编码;
MockHttpServletRequestBuilder characterEncoding(String encoding)
//:设置请求属性数据;
MockHttpServletRequestBuilder requestAttr(String name, Object value)
//:设置请求session属性数据;
MockHttpServletRequestBuilder sessionAttr(String name, Object value)/MockHttpServletRequestBuilder sessionAttrs(Map<string, object=""> sessionAttributes)
//指定请求的flash信息,比如重定向后的属性信息;
MockHttpServletRequestBuilder flashAttr(String name, Object value)/MockHttpServletRequestBuilder flashAttrs(Map<string, object=""> flashAttributes)
//:指定请求的Session;
MockHttpServletRequestBuilder session(MockHttpSession session)
// :指定请求的Principal;
MockHttpServletRequestBuilder principal(Principal principal)
//:指定请求的上下文路径,必须以“/”开头,且不能以“/”结尾;
MockHttpServletRequestBuilder contextPath(String contextPath)
//:请求的路径信息,必须以“/”开头;
MockHttpServletRequestBuilder pathInfo(String pathInfo)
//:请求是否使用安全通道;
MockHttpServletRequestBuilder secure(boolean secure)
//:请求的后处理器,用于自定义一些请求处理的扩展点;
MockHttpServletRequestBuilder with(RequestPostProcessor postProcessor)
7.4模拟上传文件MockMultipartHttpServletRequestBuilder
//:指定要上传的文件;
MockMultipartHttpServletRequestBuilder file(String name, byte[] content)/MockMultipartHttpServletRequestBuilder file(MockMultipartFile file)
7.5、常用的验证结果ResultActions
//:添加验证断言来判断执行请求后的结果是否是预期的;
ResultActions andExpect(ResultMatcher matcher)
//:添加结果处理器,用于对验证成功后执行的动作,如输出下请求/结果信息用于调试;
ResultActions andDo(ResultHandler handler)
//:返回验证成功后的MvcResult;用于自定义验证/下一步的异步处理;
MvcResult andReturn()
7.6、常用的结果验证器
//:请求的Handler验证器,比如验证处理器类型/方法名;此处的Handler其实就是处理请求的控制器;
HandlerResultMatchers handler()
//:得到RequestResultMatchers验证器;
RequestResultMatchers request()
//:得到模型验证器;
ModelResultMatchers model()
//:得到视图验证器;
ViewResultMatchers view()
//:得到Flash属性验证;
FlashAttributeResultMatchers flash()
//:得到响应状态验证器;
StatusResultMatchers status()
//:得到响应Header验证器;
HeaderResultMatchers header()
//:得到响应Cookie验证器;
CookieResultMatchers cookie()
//:得到响应内容验证器;
ContentResultMatchers content()
//:得到Json表达式验证器;
JsonPathResultMatchers jsonPath(String expression, Object ... args)/ResultMatcher jsonPath(String expression, Matcher matcher)
//:得到Xpath表达式验证器;
XpathResultMatchers xpath(String expression, Object... args)/XpathResultMatchers xpath(String expression, Map<string, string=""> namespaces, Object... args)
//:验证处理完请求后转发的url(绝对匹配);
ResultMatcher forwardedUrl(final String expectedUrl)
//:验证处理完请求后转发的url(Ant风格模式匹配,@since spring4);
ResultMatcher forwardedUrlPattern(final String urlPattern)
//:验证处理完请求后重定向的url(绝对匹配);
ResultMatcher redirectedUrl(final String expectedUrl)
//:验证处理完请求后重定向的url(Ant风格模式匹配,@since spring4);
ResultMatcher redirectedUrlPattern(final String expectedUrl)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?