当前位置: 首页 > 科技观察

SpringBoot集成JUnit5,单元测试更优雅!

时间:2023-03-19 00:48:40 科技观察

为什么使用JUnit5JUnit4应用广泛,但是语法繁琐,很多场景使用起来很麻烦,JUnit5支持lambda表达式,语法简单,代码不冗余。JUnit5易于扩展和包容,可以对接其他测试引擎。更强大的功能提供新的断言机制、参数化测试、可重复测试等新特性。ps:为什么开发者还需要测试?有必要写这么标准的单体测试吗?其实单元测试是开发者必备的技能,但是很多开发者开发任务太多,调试完就不管了。没有系统的单元测试。单元测试可以在系统重构中发挥巨大作用。然后快速测试新界面是否与重构前不同。简单介绍如图,JUnit5结构如下:JUnitPlatform:这是Junit提供的平台功能模块,通过它可以对接其他测试引擎到Junit实现接口并执行。JUnitJUpiter:这是JUnit5的核心,一个基于JUnitPlatform的引擎实现,包含了许多丰富的新特性,使自动化测试更加方便和强大。JUnitVintage:该模块是兼容JUnit3和JUnit4版本的测试引擎,使得旧版本的自动化测试在JUnit5下也能正常运行。依赖引入我们以SpringBoot2.3.1为例,引入如下依赖,防止使用旧的junit4相关接口,排除掉它们的依赖。org.springframework.bootspring-boot-starter-testtestorg.junit。vintagejunit-vintage-engine常用注解@BeforeEach:在每个单元测试方法执行之前执行一次@BeforeAll:在每个单元测试方法执行一次在每个单元测试方法执行之前(只执行一次)@DisplayName("商品存储测试"):用于指定单元测试的名称@Disabled:禁用当前单元测试,即单元测试期间跳过测试test@RepeatedTest(n):重复测试,即执行n次@ParameterizedTest:参数化测试,@ValueSource(ints={1,2,3}):参数化测试提供数据断言JUnitJupiter为To提供了强大的断言方法验证结果,需要使用java8新特性lambda表达式,都是org.junit.jupiter.api.Assertions包中的静态方法。assertTrue和assertFalse用于判断条件是否为真@Test@DisplayName("testassertionequals")voidtestEquals(){assertTrue(3<4);}assertNull和assertNotNull用于判断条件是否为null@Test@DisplayName("TestassertionNotNull")voidtestNotNull(){assertNotNull(newObject());}assertThrows用于判断执行抛出的异常是否符合预期,可以使用异常类型接收返回值进行其他操作@Test@DisplayName("测试断言抛出异常")voidtestThrows(){ArithmeticExceptionarithExcep=assertThrows(ArithmeticException.class,()->{intm=5/0;});assertEquals("/byzero",arithExcep.getMessage()));}assertTimeout用于判断执行过程是否超时@Test@DisplayName("测试断言超时")voidtestTimeOut(){StringactualResult=assertTimeout(ofSeconds(2),()->{Thread.sleep(1000);返回“结果”;});系统。out.println(actualResult);}assertAll是一个组合断言,当它里面的所有断言都被正确执行后,就会通过@Test@DisplayName("测试组合断言")voidtestAll(){assertAll("测试项目顺序",()->{//模拟用户余额扣款assertTrue(1<2,"余额不足");},()->{//模拟物品数据库扣款assertTrue(3<4);},()->{//模拟交易流进仓库asserttNotNull(newObject());});}重复测试在很多场景下,我们需要重复测试同一个接口方法,比如测试幂等接口。JUnitJupiter通过使用@RepeatedTest(n)指定需要重复的次数@RepeatedTest(3)@DisplayName("repeatedtest")voidrepeatedTest(){System.out.println("call");}参数化测试参数化测试可以根据多个参数运行多个单元测试,这里类似适合重复测试,但是每次传入的参数并没有用到。需要使用@ParameterizedTest,还需要@ValueSource提供一组数据。它支持八种基本类型,以及String和自定义对象类型,使用起来极其方便。@ParameterizedTest@ValueSource(ints={1,2,3})@DisplayName("parameterizedtest")voidparamTest(inta){assertTrue(a>0&&a<4);}嵌入式测试JUnit5提供了嵌套的单元测试功能可以更好的展示测试类之间的业务逻辑关系。我们通常有一个业务对应一个测试类,有业务关系的类其实可以写在一起。这有利于测试。而且,内联的写法可以大大减少不必要的类,精简项目,防止类爆炸等一系列问题。Copy@SpringBootTest@AutoConfigureMockMvc@DisplayName("Junit5单元测试")publicclassMockTest{//....@Nested@DisplayName("嵌入式订单测试")classOrderTestClas{@Test@DisplayName("取消订单")voidcancelOrder(){intstatus=-1;System.out.println("取消订单成功,订单状态为:"+status);}}}