【问题标题】:Type interference issue with the WebFlux WebTestClient and KotlinWebFlux WebTestClient 和 Kotlin 的类型干扰问题
【发布时间】:2017-12-30 22:31:20
【问题描述】:

我正在使用 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:类型推断失败:没有足够的信息来推断 fun isEqualTo(p0: Version!) 中的参数 T:T!请明确说明。

使用的方法具有以下签名:

<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&lt;Nothing&gt;(version) 时它会编译。但是,当 isEqualTo 结束而没有失败时,这会导致 NullPointerException。这似乎是因为 'isEqualTo' 方法返回一个值,该值现在定义为 'Nothing' 类型。

【问题讨论】:

  • 试试 response.expectBody(Version::class.java).isEqualTo(version)
  • 我试过这个选项,但是,它会导致以下错误:Kotlin: Type argument is not in its bounds: should be subtype of 'Nothing!'
  • 尝试用 Any 替换 Version。 response.expectBody(Version::class.java).isEqualTo(‌​version)
  • 新更新:如果我使用 'response.expectBoyd(Version::class.java).isEqualTo(version),它会编译。这是因为 'isEqualTo' 方法有一个 泛型并且 S 被定义为 'S extends WebTestClient.BodySpec'。但是,即使主体不为空,其结果也是空指针。使用 isEqualTo 也不会编译。它给出了一个错误,它应该是 Nothing 的子类型!

标签: kotlin type-inference spring-webflux


【解决方案1】:

此问题现已在 Kotlin 方面得到修复,请参阅 this blog post 了解更多详细信息。需要 Kotlin 1.5.30 的标志,这将是 Kotlin 1.6.0 的默认标志。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题。

    看起来解决方案是使用扩展函数.expectBody&lt;Version&gt;()

    请参考: https://github.com/spring-projects/spring-framework/issues/20251#issuecomment-453457296

    所以,您可以将代码更改为:

    import org.springframework.test.web.reactive.server.expectBody
    ......
    response<Version>.expectBody().isEqualTo(version)
    

    它应该可以工作

    【讨论】:

      猜你喜欢
      • 2019-06-22
      • 2020-10-24
      • 2015-05-09
      • 1970-01-01
      • 2020-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多