当前位置: 首页 > news >正文

JavaWeb04-JUnit

单元测试

  • 测试:是一种用来促进鉴定软件的正确性、完整性、安全性和质量的过程。

  • 阶段划分:单元测试(白盒)、集成测试(灰盒)、系统测试(黑盒)、验收测试(黑盒)

    image

  • 测试方法:白盒测试、黑盒测试及灰盒测试

    image

  • 单元测试:就是针对最小的功能单元(方法),编写测试代码对其正确性进行测试。

  • JUnit:最流行的Java测试框架之一,提供了一些功能,方便程序进行单元测试(第三方公司提供)。

对比main方法测试:

image

image

1.单元测试入门

  1. 在pom.xml中,引入JUnit的依赖
  2. 在test/java目录下,创建测试类,并编写对应的测试方法,并在方法上声明@Test注解。
  3. 运行单元测试(测试通过:绿色;测试失败:红色)

image

注意:JUnit单元测试类命名规范为:XxxxxTest【规范】。JUnit单元测试的方法,必须声明为 public void【规定】。

案例:使用JUnit,对UserService中业务方法进行单元测试

image

其中UserService中的代码为:

package com.itheima;import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;public class UserService {/*** 给定一个身份证号,计算出该用户的年龄* @param idCard 身份证号*/public Integer getAge(String idCard){if (idCard == null || idCard.length() != 18) {throw new IllegalArgumentException("无效的身份证号码");}String birthday = idCard.substring(6, 14);LocalDate parse = LocalDate.parse(birthday, DateTimeFormatter.ofPattern("yyyyMMdd"));return Period.between(parse, LocalDate.now()).getYears();}/*** 给定一个身份证号,计算出该用户的性别* @param idCard 身份证号*/public String getGender(String idCard){if (idCard == null || idCard.length() != 18) {throw new IllegalArgumentException("无效的身份证号码");}return Integer.parseInt(idCard.substring(16,17)) % 2 == 1 ? "男" : "女";}
}

可以通过身份证号计算用户的年龄和性别

UserServiceTest中对其进行功能测试

image

测试通过,计算出了年龄。

2.断言&常见注解

image

对于身份证号,倒数第二位表示性别,如果为奇数则为男性,偶数则为女性。

image

如图可知,倒数第二位是1,测试也通过了,但是逻辑上应该为男,这说明不报错不代表代码没问题。这时候就要用到断言

2.1、断言

  • JUnit提供了一些辅助方法,用来帮我们确定被测试的方法是否按照预期的效果正常工作,这种方式称为断言

    image

    提示:上述方法形参中的最后一个参数 msg ,表示错误提示信息,可以不指定(有对应的重载方法)。

测试性别:

image

测试通过

image

测试不通过,期望是男,但实际是女,说明逻辑上出现了错误,去相应方法中检查错误。

小结

1.在JUnit测试单元中,为什么要使用断言?

  • 单元测试方法运行不报错,不代表业务方法没问题。

  • 通过断言可以检测方法运行结果是否和预期一致,从而判断业务方法的正确性

  • Assertions.assertXxxx(...)
    

2.2、常见注解

  • 在JUnit中还提供了一些注解,还增强其功能,常见的注解有以下几个:

    image

package com.itheima;import org.junit.jupiter.api.*;/*** 测试类*/
public class UesrServiceTest {@BeforeAll //在所有的单元测试方法运行之前,运行一次public static void beforeAll(){System.out.println("before All");}@AfterAll //在所有的单元测试方法运行之后,运行一次public static void afterAll(){System.out.println("after All");}@BeforeEach //在每一个单元测试方法运行之前,都会运行一次public void beforeEach(){System.out.println("before Each");}@AfterEach //在每一个单元测试方法运行之后,都会运行一次public void afterEach(){System.out.println("after Each");}@Testpublic void testGetAge(){UserService userService = new UserService();Integer age = userService.getAge("100100200209291111");System.out.println(age);}@Testpublic void testGetGender(){UserService userService = new UserService();String gender = userService.getGender("10000000000000001X");System.out.println(gender);}@Testpublic void testGetGenderWithAssert(){UserService userService = new UserService();String gender = userService.getGender("10000000000000001X");//断言//Assertions.assertEquals("男",gender);Assertions.assertEquals("男",gender,"性别获取有问题");}@Testpublic void testGetGenderWithAssert2(){UserService userService = new UserService();//断言Assertions.assertThrows(IllegalArgumentException.class,()->{userService.getGender(null);});}
}

结果:

image

  /*** 参数化测试*/@ParameterizedTest@ValueSource(strings = {"10000000000000001X","10000000000000003X","10000000000000005X"})public void testGetGender2(String idCard){UserService userService = new UserService();String gender = userService.getGender(idCard);//断言Assertions.assertEquals("男",gender,"性别获取有问题");}

image

用DisplayName还可以给测试类命名

image

2.3、企业开发规范

package com.itheima;// 只保留Junit 5的导入,删除Junit 4的import org.junit.Test
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; // Junit 5的Test注解/*** 测试类*/
@DisplayName("用户信息测试类")
public class UserService2Test {private UserService userService;@BeforeEachpublic void setUp(){userService = new UserService();}/*** 测试获取性别 - null值*/@Test // 此处已修正为Junit 5的@Test@DisplayName("获取性别-null值")public void testGetGender1(){Assertions.assertThrows(IllegalArgumentException.class, () -> {userService.getGender(null);});}/*** 测试获取性别 - 空串*/@Test@DisplayName("获取性别-空串")public void testGetGender2(){Assertions.assertThrows(IllegalArgumentException.class, () -> {userService.getGender("");});}/*** 测试获取性别 - 长度不足*/@Test@DisplayName("获取性别-长度不足")public void testGetGender3(){Assertions.assertThrows(IllegalArgumentException.class, () -> {userService.getGender("110");});}/*** 测试获取性别 - 超出长度*/@Test@DisplayName("获取性别-长度超出")public void testGetGender4(){Assertions.assertThrows(IllegalArgumentException.class, () -> {userService.getGender("100000200010110111100000");});}/*** 测试获取性别 - 正常: 男*/@Test@DisplayName("获取性别-正常男性身份证")public void testGetGender5(){String gender = userService.getGender("100000200010011011");Assertions.assertEquals("男", gender);}/*** 测试获取性别 - 正常: 女*/@Test@DisplayName("获取性别-正常女性身份证")public void testGetGender6(){String gender = userService.getGender("100000200010011021");Assertions.assertEquals("女", gender);}
}

image

那么如何知道自己测试功能是否齐全

image

image

也可以借助ai生成 仅供参考

image

http://www.jsqmd.com/news/36944/

相关文章:

  • 2025 年 11 月开窗器厂家推荐排行榜,链条开窗器,机芯开窗器,配件开窗器,电动开窗器公司推荐
  • 详细介绍:用户体验就是新SEO:如何同时提升搜索者满意度和搜索排名
  • P6688 可重集 笔记
  • 哪款学习机适合小学生用?2025年11月多款主流品牌告诉你如何选
  • AIGC系统
  • noip5
  • 20232320 2024-2025-1 《网络与系统攻防技术》实验四实验报告
  • 20232326 2025-2026-1 《网络与系统攻防技术》实验四实验报告
  • #题解#洛谷P3143
  • STM32环境监测架构开发实践
  • [GESP202303 二级] 百鸡问题
  • 2025 年 11 月码垛机厂家推荐排行榜,多样板材码垛机,倒板码垛机,分拣码垛机,上料码垛机,下料码垛机,码垛机械手,全自动码垛机,龙门码垛机公司推荐
  • 2025 ICPC成都+南京游记
  • 题解 : P14461
  • MySQL表的增删改查 - 教程
  • 20232420 2025-2026-1 《网络与系统攻防技术》实验四实验报告
  • 业务用例的概念 - f
  • P11362 [NOIP2024] 遗失的赋值 题解
  • 2025 年 11 月钢塑复合管厂家推荐排行榜,PSP/衬塑/涂塑/工业/钢衬塑/化工防腐/高强度/缩合式/电磁双热熔钢塑复合管,钢塑复合管件公司推荐
  • COLMO洗衣机维修24小时售后服务点电话号码
  • 科烁集成灶维修服务丨24h在线报修
  • 比方燃气灶售后维修-全国统一24小时400中心
  • CF 2070F Friends and Pizza
  • 上菱空调维修热线电话-24小时全国统一报修
  • openharmony部署ollama
  • 【算法学习】AC自动机
  • 华凌燃气灶全国各市服务点网点热线号码
  • 20234320 2025-2026-1 《网络与系统攻防技术》实验四实验报告
  • 102302139 尚子骐 数据采集与融合作业2
  • 深入解析:Redis技术应用