一,演示項目相關信息
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)