成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一文徹底精通 Spring Boot 單元測試

開發 前端
Spring Boot提供了許多實用工具和注釋,可以在測試應用程序時提供幫助。測試支持由兩個模塊提供:spring-boot-test包含核心項,spring-boot-test-autoconfigure支持測試的自動配置。

環境:SpringBoot2.7.18

1. 簡介

Spring Boot提供了許多實用工具和注釋,可以在測試應用程序時提供幫助。測試支持由兩個模塊提供:spring-boot-test包含核心項,spring-boot-test-autoconfigure支持測試的自動配置。

Spring Boot Test不僅提供了對Spring Test的集成,還增強了mock能力,支持多種類型的測試,包括單元測試、切片測試和功能測試。

在單元測試中,我們通常關注代碼的最小可測試單元,這可以是單個程序、類、對象或方法。單元測試的目的是檢測開發者編寫的代碼或功能是否正確。通過使用Spring Boot Test,我們可以方便地編寫和執行單元測試,確保代碼的質量和正確性。

Spring Boot  Test提供了一些注解來支持不同類型的測試。例如,@Test注解用于標記單元測試方法;@WebMvcTest、@DataJpaTest等注解用于切片測試,它介于單元測試和功能測試之間;而@RunWith和@SpringBootTest等注解則用于功能測試,它一般面向某個完整的業務功能。

spring-boot-starter-test依賴提供一下庫的支持:

  • JUnit 5: 事實上的Java應用程序單元測試標準。
  • Spring Test & Spring Boot Test: 對Spring Boot應用程序的實用程序和集成測試支持。
  • AssertJ: 一個流暢的斷言庫。
  • Hamcrest: 匹配器對象庫(也稱為約束或謂詞)。
  • Mockito: 一個Java模擬框架。
  • JSONassert: JSON的斷言庫。
  • JsonPath: JSON的XPath。

2. 實戰案例

如果你使用的是JUnit 4,請不要忘記在測試中添加@RunWith(SpringRunner .class),否則注釋將被忽略。如果你使用的是JUnit 5,就不需要添加等效的@ExtendWith(SpringExtension.class),因為@SpringBootTest和其他的@…Test注解已經用它做了注解。

默認情況下,@SpringBootTest不會啟動服務器??梢允褂聾SpringBootTest的webEnvironment屬性進一步優化測試的運行方式:

  • MOCK(Default) : 加載一個web ApplicationContext并提供一個模擬的web環境。使用此注釋時,嵌入式服務器不會啟動。如果在classpath中沒有web環境,這種模式就會返回到創建常規的非web ApplicationContext。
  • RANDOM_PORT: 加載WebServerApplicationContext并提供一個真實的web環境。嵌入式服務器啟動并監聽一個隨機端口。
  • DEFINED_PORT: 加載WebServerApplicationContext并提供一個真實的web環境。嵌入式服務器啟動并監聽一個定義好的端口(從application.properties文件中)或者默認的8080端口。
  • NONE: 使用SpringApplication加載ApplicationContext,但不提供任何web環境(模擬或其他)。

2.1 什么Web類型

@SpringBootTest(properties = "spring.main.web-application-type=reactive")
public class SpringBootTest01 {
}

通過上面的配置,聲明當前web應用的類型是基于響應式的webflux。

2.2 使用應用程序參數

如果應用需要參數,可以讓@SpringBootTest使用args屬性注入參數。

@SpringBootTest(args = "--app.test=Pack")
public class MailServiceTest {
  @Test
  public void testAppArgumentsPopulated(@Autowired ApplicationArguments args) {
    assertThat(args.getOptionNames()).containsOnly("app.test") ;
    assertThat(args.getOptionValues("app.test")).containsOnly("Pack") ;
  }
}

2.3 使用模擬環境進行測試

默認情況下,@SpringBootTest不會啟動服務器,而是設置一個模擬環境來測試web端點。在Spring MVC中,可以使用MockMvc或WebTestClient查詢web端點,如下面的例子所示。

// 已知需測試的接口
@RestController
@RequestMapping("/demos")
public class DemoController {
  @GetMapping("/index")
  public Object index() {
    return "demo index" ;
  }
}
// 單元測試
@SpringBootTest
@AutoConfigureMockMvc
public class SpringBootTest02{


  @Test
  public void testMockMvc(@Autowired MockMvc mvc) throws Exception {
    mvc.perform(get("/demos/index"))
      // 期望返回狀態碼是200
      .andExpect(status().isOk())
      // 期望返回的內容是demo index1
      // 實際接口返回的是demo index
      .andExpect(content().string("demo index1"));
  }
}

測試輸出結果

圖片圖片

2.4 運行服務進行測試

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class SpringBootTest03 {


  @Test
  public void testRestTemplate(@Autowired TestRestTemplate restTemplate) throws Exception {
    String body = restTemplate.getForObject("/demos/index", String.class);
    assertThat(body).isEqualTo("123") ;
  }
}

通過RestTemplate測試接口,同時指定需要啟動server,端口隨機。最后通過斷言判斷返回結果。

圖片圖片

隨機生成的端口

圖片圖片

2.5 模擬Bean對象

Spring Boot包含一個@MockBean注解,可以用來為ApplicationContext中的bean定義一個Mockito mock??梢允褂米⑨屘砑有碌腷ean或替換單個現有的bean定義。示例代碼如下:

// 現有的一個組件
@Service
public class RemoteService{
  public String getValue(){
    return "RemoteData" ;
  }
}
// 業務處理組件
@Service
public class BusinessService {
  @Resource
  private RemoteService remoteService ;
  // 該方法用來反轉通過RemoteService#getValue返回的字符串
  public String getReverseValue(){
    return new StringBuilder(this.remoteService.getValue()).reverse().toString() ;
  }
}

測試類

@SpringBootTest
public class SpringBootTest04 {


  @Resource
  private BusinessService businessService ;
  // 模擬的bean,這將在BusinessService中使用到
  @MockBean
  private RemoteService remoteService;


  @Test
  public void exampleTest() {
    // given方法用于設置模擬對象的方法調用應返回的值或應拋出的異常
    given(this.remoteService.getValue()).willReturn("pack") ;
    String reverse = this.businessService.getReverseValue() ;
    // 這里故意寫錯,以便清晰看到結果
    assertThat(reverse).isEqualTo("kcap1") ;
  }
}

輸出結果

圖片圖片

3. 切片化測試

Spring Boot的自動配置系統對應用程序來說工作得很好,但有時對測試來說有點過頭了。只加載測試應用程序“切片”所需的配置部分通常會有所幫助。例如,你可能只想測試Spring MVC控制器是否正確映射了url,但不想在測試中涉及數據庫調用,或者想測試JPA實體,而且在測試運行時對web層不感興趣。

spring-boot-test-autoconfigure模塊包含很多注解,可以用來自動配置這樣的  "切片"。它們都以類似的方式工作,提供了一個@…Test注解來加載ApplicationContext,以及一個或多個@AutoConfigure…注解,可用于自定義自動配置設置。

3.1 自動配置SpringMVC測試

要測試Spring MVC控制器是否按預期工作,使用@WebMvcTest注解。@WebMvcTest會自動配置Spring MVC的基礎架構,并將掃描的bean限制為@Controller、@ControllerAdvice、@JsonComponent、Converter、GenericConverter、Filter、HandlerInterceptor、WebMvcConfigurer、WebMvcRegistrations和HandlerMethodArgumentResolver。當使用@WebMvcTest注解時,不會掃描常規的@Component和@ConfigurationProperties bean。@EnableConfigurationProperties可以用來包含@ConfigurationProperties bean。如下示例:

@RestController
@RequestMapping("/business")
public class BusinessController{
  @Resource
  private RemoteService remoteService ;


  @GetMapping("/info")
  public String info() {
    return this.remoteService.getValue() ;
  }
}
// 測試接口
@WebMvcTest(BusinessController.class)
public class SpringBootTest05{


  @Autowired
  private MockMvc mvc;
  @MockBean
  private RemoteService remoteService;


  @Test
  public void testInfo() throws Exception {
    // 模擬錯誤,看的清晰
    given(this.remoteService.getValue()).willReturn("pack1") ;
    this.mvc.perform(get("/business/info").accept(MediaType.TEXT_PLAIN))
      .andExpect(status().isOk())
      .andExpect(content().string("pack"));
  }
}

輸出結果:

圖片圖片

3.2 自動配置JPA測試

可以使用@DataJpaTest注釋來測試JPA應用程序。默認情況下,它會掃描@Entity類并配置Spring Data JPA存儲庫。如果類路徑中有嵌入式數據庫,它也會配置一個。默認情況下,將spring.jpa.show-sql屬性設置為true,就會記錄SQL查詢。這可以通過注解的showSql()屬性來禁用。

當使用@DataJpaTest注解時,不會掃描常規的@Component和@ConfigurationProperties bean。@EnableConfigurationProperties可以用來包含@ConfigurationProperties bean。

@DataJpaTest
// 默認是ANY;如果不修改需要你當前環境有個嵌入式的數據庫;
// 設置為NONE后,不會替換當前環境使用的數據庫
@AutoConfigureTestDatabase(replace = Replace.NONE)
public class SpringBootTest06 {
  @Autowired
  private TestEntityManager entityManager;
  @Autowired
  private UserRepository repository;


  @Test
  public void testExample(){
    User entity = new User() ;
    entity.setAge(20) ;
    entity.setName("pack") ;
    this.entityManager.persist(entity);
    User user = this.repository.findById(100001).orElse(entity);
    assertThat(user.getName()).isEqualTo("pack1");
  }
}

輸出結果

圖片圖片

同時控制臺輸出SQL

圖片

注意:默認情況下,data JPA測試是事務性的,并在每個測試結束時進行回滾。

3.3 自動配置Redis測試

你可以使用@DataRedisTest來測試Redis應用程序。默認情況下,它會掃描@RedisHash類并配置Spring Data Redis倉庫。當使用@DataRedisTest注解時,不會掃描常規的@Component和@ConfigurationProperties bean。

3.4 自動配置Rest Clients

你可以使用@RestClientTest注解來測試REST客戶端。默認情況下,它會自動配置對Jackson、GSON和Jsonb的支持,配置一個RestTemplateBuilder,并添加對MockRestServiceServer的支持。當使用@RestClientTest注解時,常規的@Component和@ConfigurationProperties bean不會被掃描。示例代碼如下:

@Service
public class RemoteService{


  @Resource
  private RestTemplate restTemplate ;
  public String remote() {
    return this.restTemplate.getForObject("http://localhost:8088/demos/cf?ids=pack", String.class) ;
  }
}
// 測試
@RestClientTest(RemoteService.class)
// 注意,我們代碼中是直接使用RestTemplate,那么這里必須設置registerRestTemplate=true
@AutoConfigureWebClient(registerRestTemplate=true)
public class SpringBootTest07{


  @Resource
  private RemoteService service;
  @Resource
  private MockRestServiceServer server;


  @Test
  public void getInfo() {
    this.server.expect(requestTo("http://localhost:8088/demos/cf?ids=pack")).andRespond(withSuccess("pack", MediaType.TEXT_PLAIN)) ;
    String greeting = this.service.remote() ;
    assertThat(greeting).isEqualTo("pack") ;
  }
}

輸出結果

圖片

成功

3.5 TestRestTemplate

TestRestTemplate是Spring的RestTemplate的一個方便的替代方案,它在集成測試中很有用。您可以獲得一個普通的模板,或者發送基本HTTP身份驗證(帶有用戶名和密碼)的模板。無論哪種情況,模板都是容錯的。這意味著它以一種測試友好的方式運行,不會對4xx和5xx錯誤拋出異常。相反,可以通過返回的ResponseEntity及其狀態代碼來檢測此類錯誤。

TestRestTemplate可以直接在集成測試中實例化,如下例所示:

public class SpringBootTest08 {


  private final TestRestTemplate template = new TestRestTemplate();
  @Test
  public void testRequest(){
    ResponseEntity<String> response = this.template.getForEntity("http://localhost:8088/demos/cf?ids=123pack", String.class) ;
    assertThat(response.getStatusCode().is2xxSuccessful()) ;
    assertThat(response.getBody()).isEqualTo("pack") ;
  }
}

輸出結果

圖片圖片

我們也可以在WebEnvironment中使用@SpringBootTest注解。RANDOM_PORT或WebEnvironment。你可以注入一個完全配置好的TestRestTemplate并開始使用它。

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class SpringBootTest09{
  @Resource
  private TestRestTemplate template;
  @Test
  public void testRequest(){
    ResponseEntity<String> response = this.template.getForEntity("http://localhost:8088/demos/cf?ids=123pack",
        String.class) ;
    assertThat(response.getStatusCode().is2xxSuccessful()) ;
    assertThat(response.getBody()).isEqualTo("\"123pack\"") ;
  }


  @TestConfiguration(proxyBeanMethods = false)
  static class RestTemplateBuilderConfiguration{
    @Bean
    RestTemplateBuilder restTemplateBuilder(){
      return new RestTemplateBuilder()
          .setConnectTimeout(Duration.ofSeconds(1))
          .setReadTimeout(Duration.ofSeconds(1)) ;
    }
  }
}


責任編輯:武曉燕 來源: Springboot全家桶實戰案例源碼
相關推薦

2023-11-25 09:41:34

GogRPCHandler

2021-09-01 12:03:49

Spring單元測試

2011-05-16 16:52:09

單元測試徹底測試

2023-09-27 23:43:51

單元測試Spring

2021-01-07 14:06:30

Spring BootJUnit5Java

2013-06-04 09:49:04

Spring單元測試軟件測試

2017-01-14 23:42:49

單元測試框架軟件測試

2024-01-11 09:35:12

單元測試Python編程軟件開發

2021-08-26 11:00:54

Spring BootJUnit5Java

2020-12-07 06:19:50

監控前端用戶

2021-07-08 10:08:03

DvaJS前端Dva

2022-02-14 22:22:30

單元測試Junit5

2021-06-30 08:45:02

內存管理面試

2023-10-27 08:15:45

2020-03-18 14:00:47

MySQL分區數據庫

2022-06-07 10:13:22

前端沙箱對象

2022-05-11 07:38:45

SpringWebFlux

2024-05-17 09:46:17

Python單元測試unittest模塊

2024-05-13 10:45:25

中介模式面向對象數量

2019-11-06 17:30:57

cookiesessionWeb
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文字幕一区在线 | 国产在线视频在线观看 | 激情视频网站 | 国产欧美一区二区三区在线看 | 国产精品久久久久久久久久久久 | 国产一区二区电影网 | www.中文字幕av| 国产日韩欧美在线观看 | 国产日韩欧美一区 | 日本欧美国产 | 日韩电影免费在线观看中文字幕 | 久草久 | 精品视频一区二区在线观看 | 国产高清精品一区二区三区 | 欧美影院 | 日韩一区二区精品 | 国产一级一级毛片 | 日本亚洲一区 | 国产精品18hdxxxⅹ在线 | 欧美在线视频网站 | 在线观看免费高清av | 成人精品鲁一区一区二区 | 五月激情综合网 | 日本高清视频网站 | 久久天堂 | 中文字幕免费中文 | 久久综合九九 | 亚洲精品一区二区 | 日韩at| 免费国产一区二区 | 97超碰人人 | 中文字幕日韩欧美一区二区三区 | 91国语清晰打电话对白 | 色综合一区二区三区 | 成年人精品视频 | 国产精品美女久久久久久久网站 | 久久小视频| 久久人人爽人人爽 | 国产精品一区二区av | 黄色网页在线观看 | 美女在线观看av |