欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot項目中使用Mockito的示例代碼

 更新時間:2019年10月28日 10:03:21   作者:阿杜的世界  
這篇文章主要介紹了SpringBoot項目中使用Mockito的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

Spring Boot可以和大部分流行的測試框架協(xié)同工作:通過Spring JUnit創(chuàng)建單元測試;生成測試數(shù)據(jù)初始化數(shù)據(jù)庫用于測試;Spring Boot可以跟BDD(Behavier Driven Development)工具、Cucumber和Spock協(xié)同工作,對應(yīng)用程序進行測試。

進行軟件開發(fā)的時候,我們會寫很多代碼,不過,再過六個月(甚至一年以上)你知道自己的代碼怎么運作么?通過測試(單元測試、集成測試、接口測試)可以保證系統(tǒng)的可維護性,當(dāng)我們修改了某些代碼時,通過回歸測試可以檢查是否引入了新的bug??偟脕碚f,測試讓系統(tǒng)不再是一個黑盒子,讓開發(fā)人員確認系統(tǒng)可用。

在web應(yīng)用程序中,對Controller層的測試一般有兩種方法:(1)發(fā)送http請求;(2)模擬http請求對象。第一種方法需要配置回歸環(huán)境,通過修改代碼統(tǒng)計的策略來計算覆蓋率;第二種方法是比較正規(guī)的思路,但是在我目前經(jīng)歷過的項目中用得不多,今天總結(jié)下如何用Mock對象測試Controller層的代碼。

在之前的幾篇文章中,我們都使用bookpub這個應(yīng)用程序作為例子,今天也不例外,準(zhǔn)備測試它提供的RESTful接口是否能返回正確的響應(yīng)數(shù)據(jù)。這種測試不同于單元測試,需要為之初始化完整的應(yīng)用程序上下文、所有的spring bean都織入以及數(shù)據(jù)庫中需要有測試數(shù)據(jù),一般來說這種測試稱之為集成測試或者接口測試。

實戰(zhàn)

通過spirng.io新建的Spring Boot項目提供了一個空的測試文件——BookPubApplicationTest.java,內(nèi)容是:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BookPubApplication.class)
public class BookPubApplicationTests {
  @Test
  public void contextLoads() {
  }
}

在pom文件中增加spring-boot-starter-test依賴,添加jsonPath依賴

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>com.jayway.jsonpath</groupId>
  <artifactId>json-path</artifactId>
</dependency>

在BookPubApplicationTest中添加測試用例

package com.test.bookpub;

import com.test.bookpub.domain.Book;
import com.test.bookpub.repository.BookRepository;
import org.junit.Before;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.boot.test.TestRestTemplate;
import org.springframework.boot.test.WebIntegrationTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.WebApplicationContext;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.hamcrest.Matchers.containsString;
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.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BookPubApplication.class)
@WebIntegrationTest("server.port:0")
public class BookPubApplicationTests {
  @Autowired
  private WebApplicationContext context;
  @Autowired
  private BookRepository bookRepository;
  @Value("${local.server.port}")
  private int port;

  private MockMvc mockMvc;
  private RestTemplate restTemplate = new TestRestTemplate();

  @Before
  public void setupMockMvc() {
    mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
  }

  @Test
  public void contextLoads() {
    assertEquals(1, bookRepository.count());
  }

  @Test
  public void webappBookIsbnApi() {
    Book book = restTemplate.getForObject("http://localhost:" + port +"/books/9876-5432-1111", Book.class);
    assertNotNull(book);
    assertEquals("中文測試", book.getPublisher().getName());
  }

  @Test
  public void webappPublisherApi() throws Exception {
    //MockHttpServletRequestBuilder.accept方法是設(shè)置客戶端可識別的內(nèi)容類型
    //MockHttpServletRequestBuilder.contentType,設(shè)置請求頭中的Content-Type字段,表示請求體的內(nèi)容類型
    mockMvc.perform(get("/publishers/1")
        .accept(MediaType.APPLICATION_JSON_UTF8))

        .andExpect(status().isOk()) 
        .andExpect(content().string(containsString("中文測試")))
        .andExpect(jsonPath("$.name").value("中文測試"));
  }
}

spring boot項目的代碼覆蓋率

使用cobertura,參考項目的github地址:spring boot template

# To create test coverage reports (in target/site/cobertura)
mvn clean cobertura:cobertura test


分析

首先分析在BookPubApplicationTests類中用到的注解:

  • @RunWith(SpringJUnit4ClassRunner.class),這是JUnit的注解,通過這個注解讓SpringJUnit4ClassRunner這個類提供Spring測試上下文。
  • @SpringApplicationConfiguration(classes = BookPubApplication.class),這是Spring Boot注解,為了進行集成測試,需要通過這個注解加載和配置Spring應(yīng)用上下文。這是一個元注解(meta-annoation),它包含了@ContextConfiguration( loader = SpringApplicationContextLoader.class)這個注解,測試框架通過這個注解使用Spring Boot框架的SpringApplicationContextLoader加載器創(chuàng)建應(yīng)用上下文。
  • @WebIntegrationTest(“server.port:0”),這個注解表示當(dāng)前的測試是集成測試(integration test),因此需要初始化完整的上下文并啟動應(yīng)用程序。這個注解一般和@SpringApplicationConfiguration一起出現(xiàn)。server.port:0指的是讓Spring Boot在隨機端口上啟動Tomcat服務(wù),隨后在測試中程序通過@Value(“${local.server.port}”)獲得這個端口號,并賦值給port變量。當(dāng)在Jenkins或其他持續(xù)集成服務(wù)器上運行測試程序時,這種隨機獲取端口的能力可以提供測試程序的并行性。

了解完測試類的注解,再看看測試類的內(nèi)部。由于這是Spring Boot的測試,因此我們可通過@Autowired注解織入任何由Spring管理的對象,或者是通過@Value設(shè)置指定的環(huán)境變量的值。在現(xiàn)在這個測試類中,我們定義了WebApplicationContext和BookRepository對象。

每個測試用例用@Test注解修飾。在第一個測試用例——contextLoads()方法中,我僅僅需要確認BookRepository連接已經(jīng)建立,并且數(shù)據(jù)庫中已經(jīng)包含了對應(yīng)的測試數(shù)據(jù)。

第二個測試用例用來測試我們提供的RESTful URL——通過ISBN查詢一本書,即“/books/{isbn}”。在這個測試用例中我們使用TestRestTemplate對象發(fā)起RESTful請求。

第三個測試用例中展示了如何通過MockMvc對象實現(xiàn)跟第二個測試類似的功能。Spring測試框架提供MockMvc對象,可以在不需要客戶端-服務(wù)端請求的情況下進行MVC測試,完全在服務(wù)端這邊就可以執(zhí)行Controller的請求,跟啟動了測試服務(wù)器一樣。

測試開始之前需要建立測試環(huán)境,setup方法被@Before修飾。通過MockMvcBuilders工具,使用WebApplicationContext對象作為參數(shù),創(chuàng)建一個MockMvc對象。

MockMvc對象提供一組工具函數(shù)用來執(zhí)行assert判斷,都是針對web請求的判斷。這組工具的使用方式是函數(shù)的鏈?zhǔn)秸{(diào)用,允許程序員將多個測試用例鏈接在一起,并進行多個判斷。在這個例子中我們用到下面的一些工具函數(shù):

  • perform(get(…))建立web請求。在我們的第三個用例中,通過MockMvcRequestBuilder執(zhí)行GET請求。
  • andExpect(…)可以在perform(…)函數(shù)調(diào)用后多次調(diào)用,表示對多個條件的判斷,這個函數(shù)的參數(shù)類型是ResultMatcher接口,在MockMvcResultMatchers這這個類中提供了很多返回ResultMatcher接口的工具函數(shù)。這個函數(shù)使得可以檢測同一個web請求的多個方面,包括HTTP響應(yīng)狀態(tài)碼(response status),響應(yīng)的內(nèi)容類型(content type),會話中存放的值,檢驗重定向、model或者header的內(nèi)容等等。這里需要通過第三方庫json-path檢測JSON格式的響應(yīng)數(shù)據(jù):檢查json數(shù)據(jù)包含正確的元素類型和對應(yīng)的值,例如jsonPath(“$.name”).value(“中文測試”)用于檢查在根目錄下有一個名為name的節(jié)點,并且該節(jié)點對應(yīng)的值是“中文測試”。

一個字符亂碼問題

  • 問題描述:通過spring-boot-starter-data-rest建立的repository,取出的漢字是亂碼。
  • 分析:使用postman和httpie驗證都沒問題,說明是Mockmvc的測試用例寫得不對,應(yīng)該主動設(shè)置客戶端如何解析HTTP響應(yīng),用get.accept方法設(shè)置客戶端可識別的內(nèi)容類型,修改后的測試用例如下:
@Test
public void webappPublisherApi() throws Exception {
  //MockHttpServletRequestBuilder.accept方法是設(shè)置客戶端可識別的內(nèi)容類型
  //MockHttpServletRequestBuilder.contentType,設(shè)置請求頭中的Content-Type字段,表示請求體的內(nèi)容類型
  mockMvc.perform(get("/publishers/1")
      .accept(MediaType.APPLICATION_JSON_UTF8))

      .andExpect(status().isOk())
      .andExpect(content().string(containsString("中文測試")))
      .andExpect(jsonPath("$.name").value("中文測試"));
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • springboot jackson自定義序列化和反序列化實例

    springboot jackson自定義序列化和反序列化實例

    這篇文章主要介紹了spring boot jackson自定義序列化和反序列化實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • java如何用反射將一個對象復(fù)制給另一個對象

    java如何用反射將一個對象復(fù)制給另一個對象

    這篇文章主要介紹了java如何用反射將一個對象復(fù)制給另一個對象問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • MyBatisCodeHelperPro最新激活方法(有效方法)

    MyBatisCodeHelperPro最新激活方法(有效方法)

    這篇文章主要介紹了MyBatisCodeHelperPro最新激活方法親測有效,非常好用,小編今天以idea2021.2.1為例給大家詳細講解,需要的朋友可以參考下
    2022-08-08
  • Java SpringBoot安全框架整合Spring Security詳解

    Java SpringBoot安全框架整合Spring Security詳解

    這篇文章主要介紹了Spring Boot整合Spring Security的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-09-09
  • springboot?Minio功能實現(xiàn)代碼

    springboot?Minio功能實現(xiàn)代碼

    這篇文章主要介紹了springboot?Minio功能實現(xiàn),本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • 淺析Android系統(tǒng)中HTTPS通信的實現(xiàn)

    淺析Android系統(tǒng)中HTTPS通信的實現(xiàn)

    這篇文章主要介紹了淺析Android系統(tǒng)中HTTPS通信的實現(xiàn),實現(xiàn)握手的源碼為Java語言編寫,需要的朋友可以參考下
    2015-07-07
  • springboot與dubbo的版本匹配問題

    springboot與dubbo的版本匹配問題

    這篇文章主要介紹了springboot與dubbo的版本匹配問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • 深入淺析JSON在java中的使用

    深入淺析JSON在java中的使用

    這篇文章主要介紹了JSON在java中的使用,包括javaBean和json的互轉(zhuǎn),List 和 json 的互轉(zhuǎn)及map 和 json 的互轉(zhuǎn),本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-04-04
  • Java判斷兩個日期相差天數(shù)的方法

    Java判斷兩個日期相差天數(shù)的方法

    這篇文章主要介紹了Java判斷兩個日期相差天數(shù)的方法,以實例形式對比分析了java進行日期換算及對比的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-10-10
  • Java大數(shù)字運算之BigInteger

    Java大數(shù)字運算之BigInteger

    在Java中提供了大數(shù)字的操作類,即 java.math.BigInteger 類與 java.math.BigDecimal 類。其中,BigInteger 類是針對大整數(shù)的處理類,這里有Integer 類的解釋,使用方法和實例,需要的朋友可以參考下。
    2017-08-08

最新評論