Junit5&Junit4

参考资料
https://www.cnblogs.com/zgq123456/p/12907757.html
https://www.cnblogs.com/zgq123456/p/12907751.html
https://zhuanlan.zhihu.com/p/111706639
JunitPref
https://www.cnblogs.com/zgq123456/p/12907772.html

Junit5

目前Java领域内最为流行的单元测试框架 ------ JUnit

Junit的最新版本JUnit5于2017年发布。

Junit 5 = Junit Platform + Junit Jupiter + Junit Vintage

Junit Platform: Junit Platform是在JVM上启动测试框架的基础,不仅支持Junit自制的测试引擎,其他测试引擎也都可以接入。

Junit Jupiter: Junit Jupiter提供了JUnit5的新的编程模型,是JUnit5新特性的核心。内部 包含了一个测试引擎,用于在Junit Platform上运行。

Junit Vintage: 由于JUnit已经发展多年,为了照顾老的项目,JUnit Vintage提供了兼容JUnit4.x,Junit3.x的测试引擎。

在这里插入图片描述
在这里插入图片描述

Dependency
Junit4

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version> // 4.12 也比较常用
    <scope>test</scope>
</dependency>

当前dependency会引入junit:4.12和hamcrest-core:1.3的包

Junit vintage engine

<dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <version>5.8.1</version>
    <scope>test</scope>
</dependency>

当前dependency会引入unit:4.13, apiguardian-api:1.1.0, hamcrest-core:1.3, junit-platform-commons:1.6.2,

junit-platform-engine:1.6.2, junit-vintage-engine:5.8.1, opentest4j:1.2.0的包

Jupiter

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.8.1</version>
    <scope>test</scope>
</dependency>

当前dependency会引入apiguardian-api:1.1.0, junit-Jupiter-api:5.8.1, junit-platform-commons:1.6.2, opentest4j:1.2.0的包

Junit4和Junit5的注解区别

Junit5Junit4说明
@Test@Test被注解的方法是一个测试方法。与 JUnit 4 相同。
@BeforeAll@BeforeClass被注解的(静态)方法将在当前类中的所有 @Test 方法前执行一次
@BeforeEach@Before被注解的方法将在当前类中的每个 @Test 方法前行。
@AfterEach@After被注解的方法将在当前类中的每个 @Test 方法后执行
@AfterAll@AfterClass被注解的(静态)方法将在当前类中的所有 @Test 方法后执行一次
@Disabled@Ignore被注解的方法不会执行(将被跳过),但会报告为已执行

Junit4中的@Test是import org.junit.Test;

Jupiter中的@Test是import org.junit.jupiter.api.Test;

断言
在Junit4和Junit5中均有标准断言

断言方法说明
assertEquals(expected, actual)如果 expected 不等于 actual ,则断言失败
assertFalse(booleanExpression)如果 booleanExpression 不是 false ,则断言失败
assertNull(actual)如果 actual 不是 null ,则断言失败
assertNotNull(actual)如果 actual 是 null ,则断言失败
assertTrue(booleanExpression)如果 booleanExpression 不是 true ,则断言失败

Junit4中任何断言失败,测试就会在该位置失败,意味着不会执行任何其他断言。例如StudentTest中的should_test_every_test

@Test
public void should_test_every_test() {
    //given when
    int expected = 6;
    int actual = 10 - 4;
    Object nullValue = null;
 
    //then
    assertEquals(expected, actual);
    assertFalse(true);
    assertNull(nullValue);
    assertTrue(false);
}

如果希望所有 断言都会执行,即使一个或多个断言失败也是如此,该怎么做呢?

可以使用Jupiter中提供的aseertAll方法


@Test
@DisplayName("test assertAll")
void should_test_every_test() {
    //given when
    int expected = 4;
    int actual = 2 + 2;
    Object nullValue = null;
 
    //then
    assertAll(
        "Assert All of these",
        () -> assertEquals(expected, actual),
        () -> assertFalse(nullValue == null),
        () -> assertNull(nullValue),
        () -> assertNotNull("Hello Word!"),
        () -> assertTrue(nullValue != null));
}

@DisplayName

可以在类和方法中添加@DisplayName注释。这个名称在生成报告时使用,这使得描述测试的目的和追踪失败更容易
运行单元测试后,点击如下位置则可生成html报告
在这里插入图片描述
(https://github.com/yanggfann/JunitProbe/blob/main/Junit4Junit5Jupiter/image/generate%20report.png)]

Student生成的单元测试报告为Test Results - StudentTest.html

StudentJupiterTest生成的单元测试报告为Test Results - StudentJupiterTest.html

校验异常
Junit4提供了@Test(expected = Exception.class)的方式来校验异常,但这种方式的缺点是,当两个不同的业务抛出相同的业务异常,
而仅仅message不同时则无法精准的校验。


@Test(expected = BusinessException.class)
public void should_throw_business_exception_when_student_name_length_more_than_10() {
    //given when
    StudentCommand.builder()
        .name(RandomStringUtils.randomAlphanumeric(11))
        .build();
}
 
@Test(expected = BusinessException.class)
public void should_throw_business_exception_when_student_description_length_more_than_20() {
    //given when
    StudentCommand.builder()
        .name(RandomStringUtils.randomAlphanumeric(9))
        .description(RandomStringUtils.randomAlphanumeric(21))
        .build();
}

当然也可以通过捕获异常的方式,再判断message,但这种方式不太优雅。


@Test
public void should_validate_message_when_student_name_length_more_than_10() {
    //given when
    try {
        StudentCommand.builder()
            .name(RandomStringUtils.randomAlphanumeric(11))
            .build();
    } catch (BusinessException e) {
        assertEquals(e.getMessage(), "The length of student name exceed 10 chars.");
    }
}

Jupiter提供了新的校验方式,Assertions.assertThrows,在Junit的4.13的版本中,Asserts.assertThrows也提供了类似的功能

@Test
@DisplayName("It tests the length of student name should less than 10 chars")
void should_throw_business_exception_when_student_name_length_more_than_10() {
    //given when
    BusinessException businessException = Assertions.assertThrows(BusinessException.class, this::buildStudentName);
 
    //then
    assertEquals(businessException.getMessage(), "The length of student name exceed 10 chars.");
}
 
private void buildStudentName() {
    StudentCommand.builder()
        .name(RandomStringUtils.randomAlphanumeric(11))
        .build();
}
 
@Test
@DisplayName("It tests the length of student description should less than 20 chars")
void should_throw_business_exception_when_student_description_length_more_than_20() {
    //given when
    BusinessException businessException = Assertions.assertThrows(BusinessException.class, this::buildStudentDescription);
 
    //then
    assertEquals(businessException.getMessage(), "The length of student name exceed 20 chars.");
}
 
private void buildStudentDescription() {
    StudentCommand.builder()
        .description(RandomStringUtils.randomAlphanumeric(21))
        .build();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值