SpringBoot使用Junit5

举报
琴岛蛏子 发表于 2022/03/21 00:15:32 2022/03/21
【摘要】 SpringBoot使用Junit5Junit5 基本语法Junit5官网 https://junit.org/junit5/PDF download.注释JUnit Jupiter 支持以下用于配置测试和扩展框架的注解。除非另有说明,所有核心注释都位于模块中的org.junit.jupiter.api包中junit-jupiter-api。注解描述@Test表示方法是测试方法。与 JUni...

SpringBoot使用Junit5

Junit5 基本语法

Junit5官网 https://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结合
如下生成两个测试方法
@TestFactory
Collection<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
@AutoConfigureMockMvc
class 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);
  }

  @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();

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。