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

Spring Boot升级2.6.4后测试用例allSatisfy重载解析歧义报错

Spring Boot升级后AssertJ的allSatisfy方法编译报错问题

问题背景

将Spring Boot从2.1.7版本升级至2.6.4版本后,原有可正常运行的测试用例出现Kotlin编译错误,对应测试代码如下:

@Test
fun `Should include id in all outbound requests`() {
    (authenticationSource as TestAuthenticationSource).setCoordinatorToken()
    val request = PersonSearch().apply {
        firstName = "Xyz"
        lastName = "Abc"
    }
    val oid = UUID.randomUUID().toString()

    client
        .post()
        .uri("/v/search/outbound")
        .headers {
            it.setBearerAuth("fakeToken")
            it.set(CORRELATION_ID, oid)
        }
        .body(Mono.just(request), PersonSearch::class.java)
        .exchange()

    assertThat(server.requestCount).isEqualTo(2)
    // 下行代码在旧版本可正常运行,升级后报错
    assertThat(server.takeAllRequests()).allSatisfy { assertThat(it.headers.toMultimap()).containsEntry(CORRELATION_ID, listOf(oid)) }

    // 尝试显式声明lambda参数it的写法仍报错
    assertThat(server.takeAllRequests()).allSatisfy { it -> assertThat(it.headers.toMultimap()).containsEntry(CORRELATION_ID, listOf(oid)) }
}

报错信息

编译时提示重载解析歧义,核心报错内容如下:

Overload resolution ambiguity. All these functions match.
public open fun allSatisfy(requirements: Consumer<in RecordedRequest!>!): ObjectArrayAssert<RecordedRequest!>! defined in org.assertj.core.api.ObjectArrayAssert
public open fun allSatisfy(requirements: ThrowingConsumer<in RecordedRequest!>!): ObjectArrayAssert<RecordedRequest!>! defined in org.assertj.core.api.ObjectArrayAssert

Kotlin编译器抛出的完整异常与上述信息一致:

Kotlin: Overload resolution ambiguity: 
public open fun allSatisfy(p0: Consumer<in RecordedRequest!>!): ObjectArrayAssert<RecordedRequest!>! defined in org.assertj.core.api.ObjectArrayAssert
public open fun allSatisfy(p0: ThrowingConsumer<in RecordedRequest!>!): ObjectArrayAssert<RecordedRequest!>! defined in org.assertj.core.api.ObjectArrayAssert

根因分析

Spring Boot 2.6.x版本内置的AssertJ版本更高,新版AssertJ为allSatisfy方法新增了入参类型为ThrowingConsumer的重载。Kotlin的SAM转换机制同时支持普通Consumer接口和允许抛出受检异常的ThrowingConsumer接口,直接传入lambda表达式时,编译器无法判定应该将lambda转换为哪一个接口实例,因此抛出重载歧义错误。

修复方案

直接显式指定lambda对应的接口类型即可消除歧义,运行逻辑和旧版本完全一致,修复代码示例:

import java.util.function.Consumer

// 其余代码不变,仅修改allSatisfy入参部分
assertThat(server.takeAllRequests()).allSatisfy(Consumer {
    assertThat(it.headers.toMultimap()).containsEntry(CORRELATION_ID, listOf(oid))
})

如果项目中大量使用该方法,也可以封装AssertJ的Kotlin扩展函数统一处理,避免每次写代码都显式声明Consumer类型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 21:33:24