写点什么

SpringBoot 使用 Junit5

用户头像
Rubble
关注
发布于: 17 小时前
SpringBoot使用Junit5

SpringBoot 使用 Junit5

Junit5 基本语法

Junit5 官网 junit.org/junit5/

 PDF download.

注释

JUnit Jupiter 支持以下用于配置测试和扩展框架的注解。

除非另有说明,所有核心注释都位于模块中的org.junit.jupiter.api包中 junit-jupiter-api。


  • @Test 表示方法是测试方法。与 JUnit 4 的 @Test 注解不同,该注解不声明任何属性,因为 JUnit Jupiter 中的测试扩展基于它们自己的专用注解进行操作。这些方法是继承的,除非它们被覆盖。

  • @ParameterizedTest 表示方法是参数化测试。这些方法是继承的,除非它们被覆盖。

  • @RepeatedTest 表示方法是重复测试的测试模板。这些方法是继承的,除非它们被覆盖。

  • @TestFactory 表示方法是动态测试的测试工厂。这些方法是继承的,除非它们被覆盖。

  • @TestTemplate 表示方法是测试用例的模板,旨在根据注册提供程序返回的调用上下文的数量多次调用。这些方法是继承的,除非它们被覆盖。

  • @TestMethodOrder 用于为注解的测试类配置测试方法执行顺序;类似于 JUnit 4 的 @FixMethodOrder. 此类注释是继承的。

  • @TestInstance 用于为带注释的测试类配置测试实例生命周期。此类注释是继承的。

  • @DisplayName 声明测试类或测试方法的自定义显示名称。此类注释不会被继承。

  • @DisplayNameGeneration 为测试类声明一个自定义显示名称生成器。此类注释是继承的。

  • @BeforeEach 表示被注解的方法应该在当前类中的每个、、、 或方法之前 执行;类似于 JUnit 4 的. 这些方法是继承的,除非它们被覆盖。 @Test@RepeatedTest@ParameterizedTest@TestFactory@Before

  • @AfterEach 表示该注释的方法应该被执行之后 每个 @Test,@RepeatedTest,@ParameterizedTest,或 @TestFactory 方法在当前类; 类似于 JUnit 4 的 @After. 这些方法是继承的,除非它们被覆盖。

  • @BeforeAll 表示该注释的方法应该被执行之前 所有 @Test,@RepeatedTest,@ParameterizedTest,和 @TestFactory 方法在当前类; 类似于 JUnit 4 的 @BeforeClass. 此类方法是继承的(除非它们被隐藏或覆盖)并且必须是 static(除非使用“每类”测试实例生命周期)。

  • @AfterAll 表示该注释的方法应该被执行之后 的所有 @Test,@RepeatedTest,@ParameterizedTest,和 @TestFactory 方法在当前类; 类似于 JUnit 4 的 @AfterClass. 此类方法是继承的(除非它们被隐藏或覆盖)并且必须是 static(除非使用“每类”测试实例生命周期)。

  • @Nested 表示被注解的类是一个非静态嵌套测试类。@BeforeAll 和 @AfterAll 方法不能直接在 @Nested 测试类中使用,除非使用“每类”测试实例生命周期。此类注释不会被继承。

  • @Tag 用于在类或方法级别声明过滤测试的标签;类似于 TestNG 中的测试组或 JUnit 4 中的类别。此类注释在类级别继承,但不在方法级别继承。

  • @Disabled 用于禁用测试类或测试方法;类似于 JUnit 4 的 @Ignore. 此类注释不会被继承。

  • @Timeout 如果测试、测试工厂、测试模板或生命周期方法的执行超过给定的持续时间,则用于使测试失败。此类注释是继承的。

  • @ExtendWith 用于以声明方式注册扩展。此类注释是继承的。

  • @RegisterExtension 用于通过字段以编程方式注册扩展。这些字段是继承的,除非它们被隐藏。

  • @TempDir 用于在生命周期方法或测试方法中通过字段注入或参数注入提供临时目录;位于 org.junit.jupiter.api.io 包中。


@ParameterizedTest 参数化测试

结合 @ValueSource @CsvSource 构建要测试的参数

@NullSource

: 提供 Null 参数 @EmptySource:提供空参数 String list map 数组

@NullAndEmptySource

组合注释,结合了 @NullSource 和的功能 @EmptySource

如测试回文的 demo


@ParameterizedTest@ValueSource(strings = { "racecar", "radar", "able was I ere I saw elba" })void palindromes(String candidate) {    assertTrue(StringUtils.isPalindrome(candidate));}
复制代码

回文方法

public static boolean isPalindrome(String str){  if(str==null||str.length()==0)  {    throw new RuntimeException("字符串为空");  }  int mid=(str.length()-1)/2;  for(int i=0;i<=mid;i++)  {    if(str.charAt(i)!=str.charAt(str.length()-1-i))    {      return false;    }  }  return true;}
复制代码


测试输出

palindromes(String) ✔

├─ [1] candidate=racecar ✔

├─ [2] candidate=radar ✔

└─ [3] candidate=able was I ere I saw elba ✔


@CsvSource 示例
@ParameterizedTest(name = "{0} + {1} = {2}")@CsvSource({    "0,    1,   1",    "1,    2,   3",    "49,  51, 100",    "1,  100, 101"})void add(int first, int second, int expectedResult) {  Calculator calculator = new Calculator();  String express = StrUtil.format("{}+{}",first,second);  // hutool calculator  assertEquals(expectedResult, calculator.calculate(express),      () -> first + " + " + second + " should equal " + expectedResult);}
复制代码

测试输出

✔add(int, int, int)

✔0 + 1 = 1

✔1 + 2 = 3

✔49 + 51 = 100

✔1 + 100 = 101

@CsvSource 中 NIL 表示 null

示例输入 结果参数列表

@CsvSource({ "apple, banana" }) "apple", "banana"

@CsvSource({ "apple, 'lemon, lime'" }) "apple", "lemon, lime"

@CsvSource({ "apple, ''" }) "apple", ""

@CsvSource({ "apple, " }) "apple", null

@CsvSource(value = { "apple, banana, NIL" }, nullValues = "NIL") "apple", "banana",null


@CsvFileSource 从 csv 文件中加载数据

@CsvFileSource(resources = "/two-column.csv", numLinesToSkip = 1)


@Timeout 超时测试

程序运行超过时间则失败

@Test@Timeout(value = 200,unit = TimeUnit.MILLISECONDS)void timeout(){  ThreadUtil.sleep(1000);}
复制代码


@DisplayName 显示名称

可以输入表情符,是不是很好玩

@Test@DisplayName("╯°□°)╯")void testWithDisplayNameContainingSpecialCharacters() {}
@Test@DisplayName("😱")void testWithDisplayNameContainingEmoji() {}
复制代码

断言 Assertions

Assertions 类提供了一些断言方法

import static org.junit.jupiter.api.Assertions.assertEquals;import static org.junit.jupiter.api.Assertions.assertNotNull;import static org.junit.jupiter.api.Assertions.assertThrows;import static org.junit.jupiter.api.Assertions.assertTimeout;import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;import static org.junit.jupiter.api.Assertions.assertTrue;

重复测试 @RepeatedTest

对同一测试执行多次,如 @Timeout 测试服务耗时,测试内容有随机变量,运行多次测试。


@RepeatedTest(value = 10, name = "{displayName} {currentRepetition}/{totalRepetitions}")  @DisplayName("Repeat!")  void customDisplayName(TestInfo testInfo) {//    assertEquals("Repeat! 1/10", testInfo.getDisplayName());  }
复制代码

@TestFactory 测试工厂

生成测试方法与 DynamicTest 结合

如下生成两个测试方法

@TestFactoryCollection<DynamicTest> dynamicTestsFromCollection() {    return Arrays.asList(        dynamicTest("1st dynamic test", () -> assertTrue(isPalindrome("madam"))),        dynamicTest("2nd dynamic test", () -> assertEquals(4, calculator.multiply(2, 2)))    );}
复制代码


SpringBoot 测试

引入 maven 依赖

<dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-test</artifactId>  <scope>test</scope></dependency>
复制代码

@SpringBootTest

会加载 springBoot 的上下文环境,之后可以使用 spring 容器中的 bean 直接 @Autowired 注入

@AutoConfigureMockMvc

自动配置 MockMvc,使用直接 @Autowired 注入


@SpringBootTest@AutoConfigureMockMvcclass SkyControllerTest {
@Autowired MockMvc mockMvc;
@Test void sky () throws Exception { MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/sky")) .andDo(MockMvcResultHandlers.print()) .andExpect(MockMvcResultMatchers.status().isOk()) .andReturn(); String content = mvcResult.getResponse().getContentAsString(); System.out.println(content); // json 格式数据 //String content = ...; mockMvc.perform(MockMvcRequestBuilders.get("/service/sky") .content(content).contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultHandlers.print()); }
@Test void deliver () throws Exception { MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/deliver").param("box","iphone")) .andDo(MockMvcResultHandlers.print()) .andExpect(MockMvcResultMatchers.status().isOk()) .andReturn(); String content = mvcResult.getResponse().getContentAsString(); System.out.println(content); }}
复制代码

若不加 @AutoConfigureMockMvc 可以手动生成 MockMvc 对象。

MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();


用户头像

Rubble

关注

还未添加个人签名 2021.06.01 加入

还未添加个人简介

评论

发布
暂无评论
SpringBoot使用Junit5