使用 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 一起使用时,该方法本身很好。让我感到困惑的是,在调试时,calendarEntityResult
有 calendarEvents
!
> 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 是不同的。
我有以下单元测试 (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 一起使用时,该方法本身很好。让我感到困惑的是,在调试时,calendarEntityResult
有 calendarEvents
!
> 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 是不同的。