偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

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

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

環(huán)境:SpringBoot2.7.18

1. 簡介

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

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

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

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

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

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

2. 實戰(zhàn)案例

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

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

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

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 使用模擬環(huán)境進行測試

默認情況下,@SpringBootTest不會啟動服務器,而是設置一個模擬環(huán)境來測試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"))
      // 期望返回狀態(tài)碼是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。可以使用注釋添加新的bean或替換單個現有的bean定義。示例代碼如下:

// 現有的一個組件
@Service
public class RemoteService{
  public String getValue(){
    return "RemoteData" ;
  }
}
// 業(yè)務處理組件
@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的自動配置系統(tǒng)對應用程序來說工作得很好,但有時對測試來說有點過頭了。只加載測試應用程序“切片”所需的配置部分通常會有所幫助。例如,你可能只想測試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注解時,不會掃描常規(guī)的@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注解時,不會掃描常規(guī)的@Component和@ConfigurationProperties bean。@EnableConfigurationProperties可以用來包含@ConfigurationProperties bean。

@DataJpaTest
// 默認是ANY;如果不修改需要你當前環(huán)境有個嵌入式的數據庫;
// 設置為NONE后,不會替換當前環(huán)境使用的數據庫
@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注解時,不會掃描常規(guī)的@Component和@ConfigurationProperties bean。

3.4 自動配置Rest Clients

你可以使用@RestClientTest注解來測試REST客戶端。默認情況下,它會自動配置對Jackson、GSON和Jsonb的支持,配置一個RestTemplateBuilder,并添加對MockRestServiceServer的支持。當使用@RestClientTest注解時,常規(guī)的@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的一個方便的替代方案,它在集成測試中很有用。您可以獲得一個普通的模板,或者發(fā)送基本HTTP身份驗證(帶有用戶名和密碼)的模板。無論哪種情況,模板都是容錯的。這意味著它以一種測試友好的方式運行,不會對4xx和5xx錯誤拋出異常。相反,可以通過返回的ResponseEntity及其狀態(tài)代碼來檢測此類錯誤。

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全家桶實戰(zhàn)案例源碼
相關推薦

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編程軟件開發(fā)

2021-08-26 11:00:54

Spring BootJUnit5Java

2022-02-14 22:22:30

單元測試Junit5

2020-12-07 06:19:50

監(jiān)控前端用戶

2021-07-08 10:08:03

DvaJS前端Dva

2022-05-11 07:38:45

SpringWebFlux

2021-06-30 08:45:02

內存管理面試

2020-03-18 14:00:47

MySQL分區(qū)數據庫

2023-10-27 08:15:45

2022-06-07 10:13:22

前端沙箱對象

2024-05-13 10:45:25

中介模式面向對象數量

2024-05-10 08:43:04

外觀模式接口系統(tǒng)

2023-12-12 07:31:51

Executors工具開發(fā)者
點贊
收藏

51CTO技術棧公眾號