• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Sunyn-blogs
博客园    首页    新随笔    联系   管理    订阅  订阅
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");
    }


    @Test
    public void testGetAge(){
        UserService userService = new UserService();
        Integer age = userService.getAge("100100200209291111");
        System.out.println(age);

    }

    @Test
    public void testGetGender(){
        UserService userService = new UserService();
        String gender = userService.getGender("10000000000000001X");
        System.out.println(gender);
    }

    @Test
    public void testGetGenderWithAssert(){
        UserService userService = new UserService();
        String gender = userService.getGender("10000000000000001X");
        //断言
        //Assertions.assertEquals("男",gender);
        Assertions.assertEquals("男",gender,"性别获取有问题");
    }

    @Test
    public 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;

    @BeforeEach
    public 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

posted on 2025-11-10 21:32  齐天大圣951  阅读(0)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3