You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AssertJ软断言调用fail()为何立即终止?如何手动触发软断言错误?

问题描述

使用AssertJ的SoftAssertions编写测试时,遍历列表并在assertSoftly中调用fail()方法,预期输出三条错误信息,但实际第一个错误就导致程序终止。实际场景是:当预期为空的列表非空时,需要为每个元素生成动态错误提示。

代码示例

package com.example;

import org.assertj.core.api.SoftAssertions;
import org.junit.jupiter.api.Test;

import java.util.List;

public class SoftAssertionsTest {
    @Test
    void testSoftAssertions() {
        List.of(1, 2, 3).forEach(element ->
                SoftAssertions.assertSoftly(softAssertions ->
                        softAssertions.fail("Ka-boom! Index: " + element)));
    }
}

预期输出

Ka-boom! Index: 1
Ka-boom! Index: 2
Ka-boom! Index: 3

实际输出

org.assertj.core.error.AssertJMultipleFailuresError: 
Multiple Failures (1 failure)
-- failure 1 --Ka-boom! Index: 1
at SoftAssertionsTest.lambda$testSoftAssertions$0(SoftAssertionsTest.java:13)

    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at by.afinny.credit.unit.repository.SoftAssertionsTest.lambda$testSoftAssertions$1(SoftAssertionsTest.java:12)
    at java.base/java.lang.Iterable.forEach(Iterable.java:75)
问题原因

你当前的写法是在每次遍历循环中都创建了一个新的SoftAssertions实例。SoftAssertions.assertSoftly()方法的逻辑是:执行传入的断言逻辑后,会立即检查该实例中收集的所有错误,一旦有错误就抛出AssertJMultipleFailuresError终止程序。所以第一次循环时,新的SoftAssertions实例收集到第一个错误后就触发了异常,后续循环根本没机会执行。

解决方法

要实现收集所有错误再统一抛出,需要复用同一个SoftAssertions实例,不要在循环内每次调用assertSoftly()。正确写法有两种:

方式一:手动创建SoftAssertions实例

@Test
void testSoftAssertions() {
    SoftAssertions softAssertions = new SoftAssertions();
    List.of(1, 2, 3).forEach(element ->
            softAssertions.fail("Ka-boom! Index: " + element));
    // 最后统一触发所有错误的检查
    softAssertions.assertAll();
}

方式二:使用assertSoftly包裹整个循环

把整个遍历逻辑放在assertSoftly()的lambda中,这样只会创建一个SoftAssertions实例,收集所有错误后再统一抛出:

@Test
void testSoftAssertions() {
    SoftAssertions.assertSoftly(softAssertions ->
            List.of(1, 2, 3).forEach(element ->
                    softAssertions.fail("Ka-boom! Index: " + element)));
}
手动触发软断言错误的方法

AssertJ中手动触发软断言错误有两种常用方式:

  • 直接调用softAssertions.fail(String message):就是你代码里用的方式,会把自定义错误信息加入软断言的错误集合。
  • 使用softAssertions.assertThat(xxx).fail(String message):结合断言语法触发错误,比如softAssertions.assertThat(element).fail("元素非法: " + element)。

内容的提问来源于stack exchange,提问作者Sergey Zolotarev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 04:10:22