什么?你还没使用过AssertJ!

AssertJ是一个流行的Java测试框架,提供了直观且易于阅读的断言方式,支持链式断言、自定义扩展,并能与JUnit、TestNG等兼容。相比于TestNG,AssertJ的链式断言使代码更清晰,错误信息更丰富,且需要编写的代码更少。此外,SoftAssertions允许按顺序执行多个断言,过程式编程风格则使代码更接近自然语言,提高可读性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AssertJ是一个流行的Java测试框架,它旨在提供一种更直观、易于阅读和编写的方式来编写断言。使用AssertJ可以帮助开发人员更轻松地编写高效且易于维护的测试代码。

以下是AssertJ的核心功能:

  1. 提升断言的灵活性 - AssertJ提供了大量的灵活的断言方法,使得编写测试代码更加简单且易于阅读。可以直接使用这些方法来断言对象、数组、集合、日期等。
  2. 支持链式断言 - AssertJ支持链式断言,使得编写清晰、易于理解的测试代码变得更加容易。
  3. 支持自定义扩展 - 如果需要更多的断言方法,可以基于自己的业务扩展断言方法来满足需求。
  4. 兼容多种测试框架 - AssertJ可以与JUnit、TestNG等多种测试框架兼容。

testng虽然也有断言方法,但AssertJ相对于TestNG来说有以下优点:

  1. 链式方式断言:AssertJ可以使用非常易读的链式表达式编写断言。这使得测试代码更加清晰和易于理解。
  2. 更好的错误信息:当断言失败时,AssertJ提供了更好的错误信息。它会告诉你预期的值和实际的值之间的差异,并提供更多的上下文信息,以便更容易地调试问题。
  3. 更少的样板代码:使用AssertJ,您需要编写的代码比使用TestNG更少。这是因为AssertJ提供了许多内置的断言方法,可以处理大量的场景。

链式断言

assertThat(object)
.assertion1()
.assertion2()
.assertion3();

在这个例子中,assertThat()方法用于创建需要进行比较的对象,并返回一个可链接的对象。可以使用任意数量的断言方法来对该对象进行比较。每个断言方法都会返回原始对象的新实例,因此可以将多个断言链接在一起,从而形成一个链式结构。

链式断言有以下优点:

1. 更容易阅读 - 使用链式断言,可以通过多行代码对同一个对象进行多次比较,从而提高了测试代码的可读性。

2. 更容易维护 - 由于链式断言将多个断言组合成一个单独的测试用例,因此它们更容易维护并且更难出错。

3. 更加灵活 - 链式断言使得用户可以轻松地添加或删除断言,从而简化了测试代码的维护过程。

自定义断言

如果需要扩展断言方法,AssertJ 同样也支持很多扩展点。通过实现 AbstractAssert接口来扩展自己的断言。

import org.assertj.core.api.AbstractAssert;

public class PersonAssert extends AbstractAssert<PersonAssert, Person> {
    public PersonAssert(Person actual) {
        super(actual, PersonAssert.class);
    }

    public static PersonAssert assertThat(Person actual) {
        return new PersonAssert(actual);
    }

    public PersonAssert hasName(String name) {
        isNotNull();
        if (!actual.getName().equals(name)) {
            failWithMessage("Expected person's name to be <%s> but was <%s>", name, actual.getName());
        }
        return this;
    }

    public PersonAssert hasAge(int age) {
        isNotNull();
        if (actual.getAge() != age) {
            failWithMessage("Expected person's age to be <%d> but was <%d>", age, actual.getAge());
        }
        return this;
    }
}

import org.testng.annotations.Test;

public class MyTest {
    @Test
    public void test() {
        Person person = new Person("John", 30);
        PersonAssert.assertThat(person).hasName("John").hasAge(30);
    }
}

以上是 AssertJ 的一些核心能力和用法,这些特性可以使测试代码更加清晰、简洁、易于理解。除了基本的断言方法之外,AssertJ 还提供了许多高级用法,可以帮助我们更好地编写测试代码。

按需执行多个断言

有时候我们需要按照某种特定的顺序执行多个断言,而不是在第一个断言失败时立即终止。这时,我们可以使用 SoftAssertions类来执行多个断言,如果有任何一个断言失败,可以在最后输出所有失败的断言。

import org.assertj.core.api.SoftAssertions;

public class MyTest {
    @Test
    public void test() {
        String expected = "Hello";
        String actual = "hello";
        
        SoftAssertions softly = new SoftAssertions();
        softly.assertThat(actual).isEqualToIgnoringCase(expected); 
        softly.assertThat(actual).hasSize(5); 
        softly.assertThat(actual).containsOnlyOnce("e");
        
        softly.assertAll();
    }
}

在上面的示例中,我们使用 SoftAssertions 类来执行多个断言。即使有一个或多个断言失败,所有断言都会执行完毕,并输出所有失败的断言。

过程式编程

AssertJ 还支持过程式编程风格,这种风格更接近于自然语言,可以使测试代码更容易阅读和理解。

import static org.assertj.core.api.Assertions.*;

public class MyTest {
    @Test
    public void test() {
        String expected = "Hello";
        String actual = "hello";
        
        assertThat(actual)
            .as("The actual value %s should be equal to the expected value %s", actual, expected)
            .isEqualToIgnoringCase(expected)
            .hasSize(5)
            .containsOnlyOnce("e");
    }
}

在上面的示例中,我们使用静态导入Assertions包的方式,以便更清晰地表达断言方法。

最后,个人将使用经历总结如下,Testng与AssertJ并非互斥关系,二者在做断言时可以相互补充各自的不足。例如testng在处理一些复杂断言场景,测试者需要自己开发断言方法,而这点恰恰可以assertJ的长处。

AssertJ 是 JAVA 的流畅断言库。示例代码:// unique entry point to get access to all assertThat methods and utility methods (e.g. entry) import static org.assertj.core.api.Assertions.*;  // common assertions assertThat(frodo.getName()).isEqualTo("Frodo"); assertThat(frodo).isNotEqualTo(sauron)                  .isIn(fellowshipOfTheRing);  // String specific assertions assertThat(frodo.getName()).startsWith("Fro")                            .endsWith("do")                            .isEqualToIgnoringCase("frodo");  // collection specific assertions assertThat(fellowshipOfTheRing).hasSize(9)                                .contains(frodo, sam)                                .doesNotContain(sauron);  // using extracting magical feature to check fellowshipOfTheRing characters name :) assertThat(fellowshipOfTheRing).extracting("name").contains("Boromir", "Gandalf", "Frodo", "Legolas")                                                   .doesNotContain("Sauron", "Elrond");  // map specific assertions, ringBearers initialized with the elves rings and the one ring bearers. assertThat(ringBearers).hasSize(4)                        .contains(entry(oneRing, frodo), entry(nenya, galadriel))                        .doesNotContainEntry(oneRing, aragorn);  // and many more assertions : dates, file, numbers, exceptions ... 标签:AssertJ
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

软件质量保障

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值