测试工程师必备:AssertJ流式断言

AssertJ

AssertJ的三大核心价值:

流式API:链式调用结构使断言逻辑更贴近自然语言

assertThat(user.getName())
    .isEqualTo("Alice")
    .startsWith("A")
    .contains("lic");

语义化方法:提供isEqualToisInstanceOf等自解释方法名

// 传统JUnit
assertEquals("expected", actual);

// AssertJ
assertThat(actual).isEqualTo("expected");

智能类型推断:自动处理null值和集合类型

assertThat(list).containsExactly("a", "b"); // 自动处理集合
assertThat(obj).isNull(); // 明确处理null值

环境搭建

Maven依赖

<dependency>
    <groupId>org.assertj</groupId>
    <artifactId>assertj-core</artifactId>
    <version>3.24.2</version>
    <scope>test</scope>
</dependency>

Gradle依赖

testImplementation 'org.assertj:assertj-core:3.24.2'

基础断言实战

对象属性验证

User user = new User("Alice", 30);

assertThat(user.getName())
    .isEqualTo("Alice")
    .isInstanceOf(String.class)
    .startsWith("A")
    .contains("lic");

assertThat(user.getAge())
    .isEqualTo(30)
    .isGreaterThan(18)
    .isLessThan(65);

集合验证

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

assertThat(names)
    .hasSize(3)
    .contains("Alice", "Bob")
    .doesNotContain("David")
    .isSorted(); // 验证自然排序

异常验证

Throwable thrown = catchThrowable(() -> {
    divide(10, 0);
});

assertThat(thrown)
    .isInstanceOf(ArithmeticException.class)
    .hasMessageContaining("by zero");

流式API

链式提取属性

assertThat(user)
    .extracting(User::getName, User::getAge)
    .containsExactly("Alice", 30);

集合分组验证

Map<String, Integer> ages = Map.of("Alice", 30, "Bob", 25);

assertThat(ages)
    .hasSize(2)
    .containsOnlyKeys("Alice", "Bob")
    .extractingByValue()
    .allMatch(age -> age > 18);

时间验证

LocalDateTime now = LocalDateTime.now();

assertThat(now)
    .isBefore(now.plusHours(1))
    .isAfter(now.minusDays(1))
    .hasYear(2023)
    .hasMonth(Month.APRIL);

自定义断言扩展

创建自定义断言

public class CustomAssertions {
    public static StringAssert assertThat(String actual) {
        return new StringAssert(actual);
    }
}

public class StringAssert extends AbstractAssert<StringAssert, String> {
    public StringAssert(String actual) {
        super(actual, StringAssert.class);
    }

    public StringAssert isPalindrome() {
        String reversed = actual.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
        String original = new StringBuilder(reversed).reverse().toString();
        
        if (!reversed.equals(original)) {
            failWithMessage("Expected <%s> to be a palindrome", actual);
        }
        return this;
    }
}

使用自定义断言

assertThat("A man, a plan, a canal: Panama")
    .as("Palindrome check")
    .isPalindrome();

与测试框架集成

JUnit 5集成

@Test
void testUserCreation() {
    User user = new User("Alice", 30);
    
    assertAll("User properties",
        () -> assertThat(user.getName()).isEqualTo("Alice"),
        () -> assertThat(user.getAge()).isEqualTo(30)
    );
}

TestNG集成

@Test
public void testListContents() {
    List<String> names = Arrays.asList("Alice", "Bob");
    
    SoftAssertions softly = new SoftAssertions();
    softly.assertThat(names).contains("Alice");
    softly.assertThat(names).hasSize(2);
    softly.assertAll();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值