spring boot单元测试之十五:用mockmvc测试返回异步结果的controller(spring boot 2.4.4)
2023-09-14 08:59:32 时间
一,演示项目相关信息
1,地址:
https://github.com/liuhongdi/asynctest
2, 功能:演示用mockmvc测试返回异步结果的controller
3,项目结构:如图:
说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest
对应的源码可以访问这里获取: https://github.com/liuhongdi/
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,java代码
1,controller/HomeController.java
@RestController @RequestMapping("/home") public class HomeController { @Autowired private HelloService helloService; /** * 异步方法 * @return */ @RequestMapping("/callable") public Callable<String> deferredResult() throws Exception { System.out.println("控制层执行线程:" + Thread.currentThread().getName()); return new Callable<String>() { @Override public String call() throws Exception { System.out.println("异步执行线程:" + Thread.currentThread().getName()); String str = helloService.task2(); Thread.sleep(1000); return str; } }; } /** * 异步方法 * @return */ @RequestMapping("/async") public String getAsynHello(){//异步 String s = helloService.asynchSayHello(); System.out.println(s); return s; } /** * 同步方法 * * @return */ @GetMapping("/sync") public String getSyncHello(){//异步 String s = helloService.synchSayHello();return s; } }
2,service/HelloService.java
@Service public class HelloService { @Resource private SleepService sleepService; //callable中调用的方法 public String task2 () throws Exception { System.out.println("异步:线程名: " +Thread.currentThread().getName()); Thread.sleep(2000); return "this is callable"; } //同步方法 public String synchSayHello() { try { //sleepService.syncSleep(); System.out.println("同步:线程名: " +Thread.currentThread().getName()); Thread.sleep(3000); return "this is sync"; } catch (InterruptedException e) { e.printStackTrace(); return "error"; } } //调用异步的asyncsleep方法 public String asynchSayHello() { try { System.out.println("异步:线程名1: " +Thread.currentThread().getName()); sleepService.asyncSleep(); return "this is async"; } catch (Exception e) { e.printStackTrace(); return "error"; } } }
3,service/SleepService.java
@Service public class SleepService { //异步方法 @Async public void asyncSleep() throws Exception{ System.out.println("异步:线程名2: " +Thread.currentThread().getName()); Thread.sleep(3000); } }
4,controller/HomeControllerTest.java
@AutoConfigureMockMvc @SpringBootTest class HomeControllerTest { @Autowired private MockMvc mockMvc; @Test @DisplayName("测试callable正确执行返回字符串") void callableResult() throws Exception { /* MvcResult result = mockMvc.perform(get("/home/callable")) //执行请求 .andExpect(request().asyncStarted()) //.andExpect(request().asyncResult(CoreMatchers.instanceOf(User.class))) //默认会等10秒超时 .andReturn(); mockMvc.perform(asyncDispatch(result)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$.id").value(1)); */ MvcResult mvcResult = mockMvc.perform(get("/home/callable")) .andExpect(request().asyncStarted()) .andReturn(); mockMvc.perform(asyncDispatch(mvcResult)) .andExpect(status().isOk()) .andExpect(content().string("this is callable")); } @Test @DisplayName("测试callable不正确执行返回字符串") void deferredResult() throws Exception { MvcResult mvcResult = mockMvc.perform(get("/home/callable") .contentType(MediaType.APPLICATION_FORM_URLENCODED)) .andReturn(); String content = mvcResult.getResponse().getContentAsString(); assertThat(content, equalTo("")); } @Test @DisplayName("测试async返回字符串") void getAsynHello() throws Exception { MvcResult mvcResult = mockMvc.perform(get("/home/async") .contentType(MediaType.APPLICATION_FORM_URLENCODED)) .andReturn(); String content = mvcResult.getResponse().getContentAsString(); assertThat(content, equalTo("this is async")); } @Test @DisplayName("测试sync返回字符串") void getSyncHello() throws Exception { MvcResult mvcResult = mockMvc.perform(get("/home/sync") .contentType(MediaType.APPLICATION_FORM_URLENCODED)) .andReturn(); String content = mvcResult.getResponse().getContentAsString(); assertThat(content, equalTo("this is sync")); } }
三,测试效果
四,备注
1,controller在返回callable结果时,mockmvc的请求结果会为空
2,@Async注解需要添加到另一个类中的方法上调用,
不能调用本类中的async方法,
否则会不生效
五,查看spring boot的版本:
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.4.4)
相关文章
- Spring 全家桶之 Spring Boot 2.6.4(三)- Logging
- 横跨Java后端关键技术,Spring Boot终极体系做到了
- Spring Boot默认数据库连接池HikariPool
- spring整合mybatis步骤_spring整合了哪些框架
- spring boot整合shiro_Spring框架介绍及使用
- 基于Spring Boot、Vue的考试报名系统设计与实现-前后端分离-课程设计-毕业设计一键部署版
- Spring循环依赖-spring源码详解(四)
- 如何定制化Spring Boot Starter,这次我终于学会了
- 软件测试|Spring Boot 的 RESTful API 设计与实现
- Spring 6.0 重磅发布!最低支持 Java 17 !!
- Spring Framework 6.0 RC1 发布
- Spring Boot 2.x基础教程:使用@Scheduled实现定时任务
- Payment Spring Boot 1.0.2.RELEASE 发布,接入微信支付分、先享卡功能
- Spring Cloud Stream应用程序开发-集成Spring Boot应用程序示例
- 基于Spring boot的外卖项目 瑞吉外卖Day11 实现Mysql读写分离
- Spring Cloud Stream 高级特性-消息拦截器
- Spring Cloud Security OAuth2的授权模式授权码模式(二)
- 嵌入式Redis服务器在Spring Boot测试中的使用教程
- Spring配置bean的详细知识详解架构师
- spring boot–用于简便快捷的搭建基于spring的独立可运行的应用详解编程语言
- Spring中的内部Bean详解编程语言
- 吐血整理 20 道 Spring Boot 面试题,我经常拿来面试别人!详解编程语言
- Spring Boot 主类及目录结构介绍详解编程语言
- Spring Boot 核心配置文件 bootstrap & application 详解。编程语言
- Spring Boot(十四):spring boot整合shiro-登录认证和权限管理详解编程语言
- Spring Boot 2 + JPA / Hibernate 5 注入 SessionFactory 的正确姿势详解编程语言