WebFlux WebTestClient 和 Kotlin 的类型干扰问题
Type interference issue with the WebFlux WebTestClient and Kotlin
我正在使用 Spring Webflux 和 Kotlin 为新应用程序构建原型。 Spring Webflux 包含一个用于单元测试的 WebTestClient。根据文档,我应该能够像这样测试 REST 调用的结果:
@Test
fun getVersion_SingleResult_ContentTypeJson_StatusCodeOk_ContentEqualsVersion() {
//given
var version = Version("Test", "1.0")
val handler = ApiHandler(version!!)
val client = WebTestClient.bindToRouterFunction(ApiRoutes(handler).apiRouter()).build()
//expect
val response = client.get().uri("/api/version/").exchange()
response.expectStatus().isOk
response.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
response.expectBody(Version::class.java).isEqualTo(version)
}
但是,我 运行 遇到了一些类型干扰问题。问题在于 'expectBody' 和 'isEqualTo' 的组合。
我得到的错误是:
Kotlin: Type inference failed: Not enough information to infer parameter T in fun isEqualTo(p0: Version!): T! Please specify it explicitly.
使用的方法具有以下签名:
<B> WebTestClient.BodySpec<B, ?> expectBody(Class<B> var1);
public interface BodySpec<B, S extends WebTestClient.BodySpec<B, S>> {
<T extends S> T isEqualTo(B var1);
}
遗憾的是,我 运行 了解我对泛型的知识以及 Kotlin 和 Java 之间的差异,这意味着我不确定我应该如何指定它。
编辑:正如我在下面所说的,它在我使用 isEqualTo<Nothing>(version)
时编译。但是,当 isEqualTo 没有失败结束时,这会导致 NullPointerException。这似乎是因为 'isEqualTo' 方法 returns 一个值,现在被定义为 'Nothing' 类型。
此问题现已在 Kotlin 端修复,请参阅 this blog post 了解更多详细信息。需要 Kotlin 1.5.30 的标志,并将成为 Kotlin 1.6.0 的默认标志。
我运行遇到了同样的问题。
看起来解决方案是使用扩展函数.expectBody<Version>()
请参考:
https://github.com/spring-projects/spring-framework/issues/20251#issuecomment-453457296
因此,您可以将代码更改为:
import org.springframework.test.web.reactive.server.expectBody
......
response<Version>.expectBody().isEqualTo(version)
它应该有效
我正在使用 Spring Webflux 和 Kotlin 为新应用程序构建原型。 Spring Webflux 包含一个用于单元测试的 WebTestClient。根据文档,我应该能够像这样测试 REST 调用的结果:
@Test
fun getVersion_SingleResult_ContentTypeJson_StatusCodeOk_ContentEqualsVersion() {
//given
var version = Version("Test", "1.0")
val handler = ApiHandler(version!!)
val client = WebTestClient.bindToRouterFunction(ApiRoutes(handler).apiRouter()).build()
//expect
val response = client.get().uri("/api/version/").exchange()
response.expectStatus().isOk
response.expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
response.expectBody(Version::class.java).isEqualTo(version)
}
但是,我 运行 遇到了一些类型干扰问题。问题在于 'expectBody' 和 'isEqualTo' 的组合。
我得到的错误是:
Kotlin: Type inference failed: Not enough information to infer parameter T in fun isEqualTo(p0: Version!): T! Please specify it explicitly.
使用的方法具有以下签名:
<B> WebTestClient.BodySpec<B, ?> expectBody(Class<B> var1);
public interface BodySpec<B, S extends WebTestClient.BodySpec<B, S>> {
<T extends S> T isEqualTo(B var1);
}
遗憾的是,我 运行 了解我对泛型的知识以及 Kotlin 和 Java 之间的差异,这意味着我不确定我应该如何指定它。
编辑:正如我在下面所说的,它在我使用 isEqualTo<Nothing>(version)
时编译。但是,当 isEqualTo 没有失败结束时,这会导致 NullPointerException。这似乎是因为 'isEqualTo' 方法 returns 一个值,现在被定义为 'Nothing' 类型。
此问题现已在 Kotlin 端修复,请参阅 this blog post 了解更多详细信息。需要 Kotlin 1.5.30 的标志,并将成为 Kotlin 1.6.0 的默认标志。
我运行遇到了同样的问题。
看起来解决方案是使用扩展函数.expectBody<Version>()
请参考: https://github.com/spring-projects/spring-framework/issues/20251#issuecomment-453457296
因此,您可以将代码更改为:
import org.springframework.test.web.reactive.server.expectBody
......
response<Version>.expectBody().isEqualTo(version)
它应该有效