最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何測試Spring MVC應(yīng)用

 更新時間:2020年10月12日 14:33:33   作者:Ricky  
這篇文章主要介紹了如何測試Spring MVC應(yīng)用,幫助大家更好的理解和使用spring框架,感興趣的朋友可以了解下

Spring的依賴注入使得我們的代碼非常容易進行單元測試——@Controller, @Service@Entity等注解標(biāo)注的類基本都是POJO(plain old Java object),也就是說很少依賴于Spring容器本身的API。我們可以非常容易地使用JUnit或TestNG編寫測試代碼。另一方面,對于三層架構(gòu)的Spring Web應(yīng)用(Controller, Service, DAO),使用Mock活Stub方法也能夠更好的來測試我們的代碼邏輯。例如Service層代碼的單元測試中,依賴的DAO(或Repository)對象都是根據(jù)應(yīng)用測試需求Mock出來的,而不需要真正去訪問數(shù)據(jù)庫。

Spring Web測試

在對Spring Web應(yīng)用中的@Controller代碼進行單元測試的過程中,一般的方法是創(chuàng)建@Controller對象,同時將它依賴的一些Mock對象——例如MockHttpServletRequest, MockHttpServletResponse(都由spring-test模塊提供,無需自己編寫)作為@Controller方法的參數(shù)。但是對于處理Web請求的@Controller代碼來說,僅僅測試Handler方法里的代碼是遠遠不夠的,對于一個處理HTTP請求的@Controller`,我們還需要測試:

  • @RequestMapping路由是否正確
  • 數(shù)據(jù)綁定、類型轉(zhuǎn)換、校驗邏輯是否正確——數(shù)據(jù)包括URL參數(shù)、表單、@PathVariable
  • @InitBinder, @ModelAttribute, @ExceptionHandler等注解的方法或?qū)傩杂嬎氵^程

上述過程貫穿于HTTP請求處理的生命周期中,所以對于Spring Web應(yīng)用中@Controller代碼單元測試的概念,應(yīng)該做一些擴充——不僅僅局限于代碼本身,也要結(jié)合MVC框架中的各個處理過程。

本文接下來的內(nèi)容代碼,都以Spring Boot為例,首先假設(shè)我們通過Spring Boot創(chuàng)建了一個最簡單的Web Mvc應(yīng)用——包含了一個最簡單的Conroller,處理/users/{id}對應(yīng)的HTTP請求,返回值是id={id}(通過String.format()方法),那么可以為它創(chuàng)建如下測試代碼:

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringMvcTestDemoApplication.class)
@WebAppConfiguration
public class SpringMvcTestDemoApplicationTests {

  private MockMvc mockMvc;

  @Before
  public void init() {
    this.mockMvc = MockMvcBuilders.standaloneSetup(new UserController()).build();
  }

  @Test
  public void getUserById() throws Exception {
    long id = 1;
    this.mockMvc.perform(get("/users/" + id))
        .andExpect(status().isOk())
        .andExpect(content().string("id=" + id));
  }

}

運行上述測試時,很容易從控制臺中的日志發(fā)現(xiàn),SpringJUnit4ClassRunner創(chuàng)建了一個Spring Web應(yīng)用上下文,并且在其中進行了Web Mvc框架的配置——這里是注冊@RequestMapping方法。接下來mockMvc.perform()方法實際上向該Spring Web應(yīng)用發(fā)起了一個HTTP請求:

  • 請求的url為/users/{id}
  • andExpect()方法也就是測試中常用的Assert
  • status()用于檢查返回狀態(tài)嗎,這里是200
  • content()用于檢查內(nèi)容

如果我們不小心將@RequestMapping的路由路徑寫錯,那么這里運行的結(jié)果一定不會是status().isOk(),這也就完成了對HTTP請求路由的測試。接下來我們將繼續(xù)探索MVC框架中的其他方面。

Mock Service

在Spring Web應(yīng)用三層結(jié)構(gòu)里,Controller層代碼通常會調(diào)用Service層代碼,例如:

@RestController
public class UserController {

  @Autowired
  private UserService userService;

  @RequestMapping(value = "/users/{id}", method = GET)
  public String get(@PathVariable("id") long id) {
    String username = userService.getUsername(id);
    return String.format("username=%s", username);
  }
}

UserController進行單元測試需要排除Service代碼的影響,所以需要對Service進行Mock,這里我們使用Mockito框架,在Spring上下文中Mock一個UserService對象:

@Configuration
public class TestContext {

  @Bean
  public UserService userServiceMock() {
    return Mockito.mock(UserService.class);
  }
}

同時通過Mockito的API來MockUserService.getUsername(long id)方法,@Controller的測試代碼如下:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {
    SpringMvcTestDemoApplication.class,
    TestContext.class
})
@WebAppConfiguration
public class SpringMvcTestDemoApplicationTests {

  @Autowired
  UserService userService;

  @Autowired
  UserController controller;

  MockMvc mockMvc;

  @Before
  public void init() {
    this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
  }

  @Test
  public void getUserById() throws Exception {
    long id = 1L;
    String ricky = "Ricky";
    Mockito.when(userService.getUsername(id)).thenReturn(ricky);
    this.mockMvc.perform(get("/users/" + id))
        .andExpect(status().isOk())
        .andExpect(content().string("username=" + ricky));
  }

}

由于需要進行依賴注入,所以UserServiceUserController都使用@Autowired注解。Mockito.when(userService.getUsername(id)).thenReturn(ricky);表明userService.getUsername()方法的參數(shù)為1L時,返回值為"Ricky",Mockito提供能很多強大的Mock API,更多用法請參考官方文檔。

測試REST API

當(dāng)我們構(gòu)建REST服務(wù)時,大多數(shù)情況會使用JSON作為數(shù)據(jù)交換格式,Spring MVC測試框架同樣提供了一種簡潔的方式對JSON結(jié)果進行斷言,假設(shè)現(xiàn)在有@Controller如下:

@RequestMapping(value = "/users/{id}/json", method = GET)
public User getUser(@PathVariable("id") long id) {
  String username = userService.getUsername(id);
  return new User(id, username);
}

static class User {
  public long id;
  public String username;
  //構(gòu)造方法,Getter/Setter略
}

實際應(yīng)用返回的JSON數(shù)據(jù)是:

{
 "id": 1,
 "username": "Ricky"
}

測試代碼可以這樣斷言:

@Test
public void getUser() throws Exception {
  this.mockMvc.perform(get("/users/{id}/json", id).accept(MediaType.APPLICATION_JSON))
      .andExpect(status().isOk())
      .andExpect(jsonPath("$.id").value(id.intValue()))
      .andExpect(jsonPath("$.username").value(ricky));
}

$.id, $.username都是JsonPath提供的JSON表達式,可以通過jsonPath、value()等方法來輕松對JSON數(shù)據(jù)進行斷言而不需要自己編寫JSON文本處理。

以上就是如何測試Spring MVC應(yīng)用的詳細(xì)內(nèi)容,更多關(guān)于測試Spring MVC應(yīng)用的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java?枚舉的常用技巧匯總

    Java?枚舉的常用技巧匯總

    在Java中,枚舉類型是一種特殊的數(shù)據(jù)類型,允許定義一組固定的常量,默認(rèn)情況下,toString方法返回枚舉常量的名稱,本文提供了一個完整的代碼示例,展示了如何在Java中通過重寫枚舉的toString方法來展示枚舉實例的字段信息,感興趣的朋友一起看看吧
    2025-01-01
  • Java實現(xiàn)解析第三方接口返回的json

    Java實現(xiàn)解析第三方接口返回的json

    在實際開發(fā)過程中,免不了和其他公司進行聯(lián)調(diào),調(diào)用第三方接口,這個時候我們就需要根據(jù)對方返回的數(shù)據(jù)進行解析,獲得我們想要的字段,下面我們就來看看具體有哪些方法吧
    2024-01-01
  • SpringBoot使用jasypt加解密密碼的實現(xiàn)方法

    SpringBoot使用jasypt加解密密碼的實現(xiàn)方法

    這篇文章主要介紹了SpringBoot使用jasypt加解密密碼的實現(xiàn)方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • WIN10系統(tǒng)中添加bat腳本重啟jar服務(wù)

    WIN10系統(tǒng)中添加bat腳本重啟jar服務(wù)

    在bat腳本中執(zhí)行java服務(wù),命令與cmd中類似,下面這篇文章主要給大家介紹了關(guān)于WIN10系統(tǒng)中添加bat腳本重啟jar服務(wù)的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • Mybatis在insert插入操作后如何返回主鍵id問題

    Mybatis在insert插入操作后如何返回主鍵id問題

    這篇文章主要介紹了Mybatis在insert插入操作后如何返回主鍵id問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • java多線程編程之使用Synchronized塊同步變量

    java多線程編程之使用Synchronized塊同步變量

    我們可以通過synchronized塊來同步特定的靜態(tài)或非靜態(tài)方法。要想實現(xiàn)這種需求必須為這些特性的方法定義一個類變量,然后將這些方法的代碼用synchronized塊括起來,并將這個類變量作為參數(shù)傳入synchronized塊
    2014-01-01
  • java必學(xué)必會之方法的重載(overload)

    java必學(xué)必會之方法的重載(overload)

    java必學(xué)必會之方法的重載,介紹了方法的重載、構(gòu)造方法的重載,想要學(xué)好java方法的重載的朋友一定要好好閱讀這篇文章
    2015-12-12
  • Mybatis Plus代碼生成器(時間管理大師)

    Mybatis Plus代碼生成器(時間管理大師)

    這篇文章主要介紹了Mybatis Plus代碼生成器(時間管理大師)的相關(guān)知識,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • 詳解Java線程池的增長過程

    詳解Java線程池的增長過程

    在本篇文章里小編給大家整理的是關(guān)于Java線程池的增長過程以及相關(guān)知識點,需要的朋友們可以參考下。
    2019-08-08
  • java如何通過IP解析地理位置

    java如何通過IP解析地理位置

    這篇文章主要介紹了java如何通過IP解析地理位置的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評論

千阳县| 台北市| 祁阳县| 灵山县| 芦山县| 高淳县| 湘乡市| 兰西县| 临夏县| 奇台县| 西城区| 鄂尔多斯市| 淳安县| 元谋县| 营口市| 阿城市| 东乡县| 东兰县| 通海县| 庆城县| 卓资县| 井陉县| 和硕县| 金堂县| 长泰县| 涿鹿县| 镇雄县| 灌阳县| 通化市| 克拉玛依市| 郓城县| 青河县| 岐山县| 上高县| 新疆| 介休市| 兴海县| 普安县| 石狮市| 唐山市| 淮北市|