使用 Spring WebFlux 进行测试时,来自 DTO 的内部列表为空

Inner list from DTO is null while testing with Spring WebFlux

我有以下单元测试 (JUnit 5):

FluxExchangeResult<CalendarDTO> calendarEntityResult = client.get()
                .exchange()
                .expectStatus().isOk()
                .expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
                .returnResult(CalendarDTO.class);

        assertNotNull(calendarEntityResult);
        final Flux<CalendarDTO> responseBody = calendarEntityResult.getResponseBody();
        responseBody.flatMap(calendarDTO -> {
            assertNotNull(calendarDTO);
            final List<AppointmentDTO> calendarEvents = calendarDTO.getCalendarEvents();
            assertNotNull(calendarEvents);
            assertFalse(calendarEvents.isEmpty());

            return Flux.just(calendarEvents);
        }).map(calendarEvents ->
            calendarEvents.get(0)
        ).doOnNext(appointmentDTO ->
            assertEquals(appointmentDTO, validAppointmentDTO())
        ).subscribe();
        /*StepVerifier.create(responseBody)
            .assertNext(calendarDTO -> {
                assertNotNull(calendarDTO);
                final List<AppointmentDTO> calendarEvents = calendarDTO.getCalendarEvents();
                assertNotNull(calendarEvents);
                assertFalse(calendarEvents.isEmpty());

                final AppointmentDTO appointmentDTO = calendarEvents.get(0);
                assertNotNull(appointmentDTO);
                assertEquals(validAppointmentDTO(), appointmentDTO);
            })
        .expectComplete()
        .verify();*/

由于某种原因,assertNotNull(calendarEvents); 失败了。当 运行 与 Postman 一起使用时,该方法本身很好。让我感到困惑的是,在调试时,calendarEntityResultcalendarEvents!

> GET /appointments
> WebTestClient-Request-Id: [1]

No content

< 200 OK OK
< Content-Type: [application/json;charset=UTF-8]
< Content-Length: [377]

{"data":{"calendarEvents":[{"id":null,"startTime":"2020-01-16T13:19:37.510-06:00","endTime":"2020-01-16T14:19:37.511-06:00","timeZoneStart":"America/Regina","timeZoneEnd":"America/Regina","summary":"unit test summary","description":"unit test description","organizerName":"Developer","organizerEmail":"developer@dev.com","status":null,"alarm":15}]},"notifications":null}

注释代码给出了相同的结果。需要明确的是,DTO 本身不是空的;问题是 calendarEvents 数组。有可能我做错了什么,因为我通常是反应式编程的新手,所以代码改进是最受欢迎的。我是否以错误的方式提取数据?

断言任何类型的通量时,您都应该使用 stepverifier。会让你的生活更轻松。

    final Flux<String> responseBody = testClient.get()
            .exchange()
            .expectStatus()
            .isOk()
            .returnResult(String.class)
            .getResponseBody();

    StepVerifier.create(responseBody)
            .assertNext(s -> assertEquals(s, "Foo"))
            .assertNext(s -> assertEquals(s, "Bar"));

原来根 DTO 已经被包装到另一个 DTO 中。它可能导致 getResponseBody() 误解列表的内容并将其默认为空。为好奇留下回应:

final Flux<AppointmentCalendarResponse> responseBody = client.get()
                .exchange()
                .expectStatus().isOk()
                .expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
                .returnResult(AppointmentCalendarResponse.class)
                .getResponseBody();

        StepVerifier.create(responseBody)
                .assertNext(data -> {
                    CalendarDTO calendarDTO = data.getData();
                    final List<AppointmentDTO> calendarEvents = calendarDTO.getCalendarEvents();
                    assertNotNull(calendarEvents);
                })
        .expectComplete()
        .verify();

你们使用的是同一个数据库吗?

因为通常 DB 测试和 DB Dev 是不同的。