当前位置: 首页 > 知识库问答 >
问题:

Spring WebFluxTest在使用Flux作为响应时的奇怪行为

艾雪风
2023-03-14

在使用Spring WebFlux(5.2.6版)测试以下控制器时,我目前面临一个奇怪的问题

@RestController
@RequestMapping(path = "/address", produces = MediaType.APPLICATION_JSON_VALUE)
public class AddressController {

    @GetMapping(path = "/postcode")
    public Flux<String> listPostCodes(...) {
        return Flux.just("4711", "4712");
    }

    @GetMapping(path = "/cities")
    public Flux<City> listCities() {
        return Flux.just(new City("foo"), new City("bar"));
    }

}

控制器使用Spring webflux starter和一个简单的主类嵌入到“hello world”Spring启动应用程序中。ClassCity只有一个属性“name”。

现在,我有以下测试(Junit5)来确保上述控制器的响应

@SpringWebFluxTest
public AddressControllerTest {

    @Test
    public void postcodes() {
        webTestClient.get()
            .uri("/address/postcode")
            .exchange()
            .expectStatus()
            .isOk()
            .expectBody()
            .jsonPath("$")
            .isArray()
            .jsonPath("$[0]")
            .isEqualTo("4711")
    }

    @Test
    public void cities() {
        webTestClient.get()
            .uri("/address/cities")
            .exchange()
            .expectStatus()
            .isOk()
            .expectBody()
            .jsonPath("$")
            .isArray()
            .jsonPath("$[0].name")
            .isEqualTo("foo")
    }

}

你以为两次考试都能通过?我也是。不幸的是,第一个失败了,它告诉我响应体根不是json数组,而是一个长字符串:

Expected: an instance of java.util.List
 but: <47114712L> is a java.lang.Long

为什么?两个响应都是Flux,所以我希望两个响应体都是一个数组,但前提是元素不是“简单”类型,这似乎在测试中有效。如果我使用postman断言行为一切都完全按照预期工作,所以我会以某种方式假设一个测试问题。

有人能给我解释一下吗?或者有什么解决办法?

提前谢谢

共有1个答案

颜欣怡
2023-03-14

这不是测试的问题,实际行为不是你所期望的。

两个响应都是通量,所以我希望两个响应体都是一个数组

通量与列表不同。它是一个数据流,可以逐字输出,也可以在完成后收集到其他数据结构中(列表就是一个例子)

当然,在这种情况下,指定的内容类型表示您希望在可能的情况下将Flux收集到一个列表中,但情况并非普遍如此。有了POJOs,收藏

如果需要JSON数组,则需要使用:

@GetMapping(path = "/postcode")
public Mono<List<String>> listPostCodes() {
    return Flux.just("4711", "4712").collectList();
}

为了提前消除这种方法的常见神话——您不会使用CollectList()进行阻塞,并且您不会在封面下丢失任何东西(因为即使您使用Flux,框架仍然需要在内部收集到列表以返回JSON数组。)

 类似资料:
  • 我有一个表单组件,它从其父级获取其状态。表单组件只呈现一些输入字段和其他字段。 父组件使用useReucer并将值向下传递给表单组件。 有两个父组件,一个允许用户使用表单创建,另一个允许他们编辑。 在编辑父组件中,我使用useEffect从api获取数据,并从服务器设置初始状态。 在开发构建中,当组件呈现时,有时会出现以下错误: 超过最大更新深度。当组件在componentWillUpdate或c

  • 我有以下代码来解析一个JSON文件: 要处理以下JSON文件: 如果我执行此代码,我将收到以下错误: 所以我开始一步一步地调试应用程序,看看part processing()中的哪个代码部分抛出了这个异常。令人惊讶的是,那里的所有代码都正常执行:没有抛出异常,也没有返回结果I except。 更让我惊讶的是,当我稍微改变第一种方法的代码时,它可以在不产生异常的情况下工作。 我不知道println方

  • 我正在使用Mapstruct映射将一个POJO转换为另一个POJO模型 以下是mapstruct自动生成的方法 该方法基本上获取源POJO的映射,并将其转换为目标模型的映射。生成正在通过。 当我运行代码时,我在这个方法中得到了ClassCast异常:HeaderAttributeGenericDataTypeMaptoStringEnergiectAttributeDataMap 堆栈跟踪: 我还

  • 问题内容: 请考虑以下示例Java类(下面的pom.xml): 我写一个FileOutputStream,然后尝试删除该文件, 而不先关闭Stream 。这是我最初的问题,当然是错误的,但它导致了一些奇怪的发现。 在Windows 7上运行主方法时,它将产生以下输出: 为什么第一次调用Files.delete()不会引发异常? 为什么以下对Files.exist()的调用返回false? 为什么无

  • 这个程序打印00,但是如果我注释掉a.store和b.store,而取消注释a.fetch_add和b.fetch_add,这做了完全相同的事情,即都设置了a=1,b=1的值,我永远不会得到00。 是我错过了什么,还是“00”按标准永远不会出现? 下面打印00。 下图从不打印00 再看看这个,多线程原子a b打印00 for memory_order_refield

  • 我有以下代码: 假设我现在将电脑的时区设置为太平洋时间(PDT为UTC-7),则打印 2012年6月29日星期五08:15:00太平洋标准时间 PDT不是比IST(印度标准时间)晚12.5小时吗?这个问题在任何其他时区都不会发生-我尝试了UTC、PKT、MMT等,而不是日期字符串中的IST。Java中有两个IST吗? 注意:实际代码中的日期字符串来自外部源,因此我不能使用GMT偏移量或任何其他时区