如何测试相等的数据类与OffsetDateTime属性?



我在DTO和Entity中定义了一个属性:

val startDate: OffsetDateTime,

dto有一个toEntity方法:

data class SomeDTO(
val id: Long? = null,
val startDate: OffsetDateTime,
) {
fun toEntity(): SomeEntity {
return SomeEntity(
id = id,
startDate = startDate,
)
}
}

和控制器

@RestController
@RequestMapping("/some/api")
class SomeController(
private val someService: SomeService,
) {
@PostMapping("/new")
@ResponseStatus(HttpStatus.CREATED)
suspend fun create(@RequestBody dto: SomeDTO): SomeEntity {
return someService.save(dto.toEntity())
}
}

我有一个失败的测试:

@Test
fun `create Ok`() {
val expectedId = 123L
val zoneId = ZoneId.of("Europe/Berlin")
val dto = SomeDTO(
id = null,
startDate = LocalDate.of(2021, 4, 23)
.atStartOfDay(zoneId).toOffsetDateTime(),
)
val expectedToStore = dto.toEntity()
val stored = expectedToStore.copy(id = expectedId)
coEvery { someService.save(any()) } returns stored
client
.post()
.uri("/some/api/new")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(dto)
.exchange()
.expectStatus().isCreated
.expectBody()
.jsonPath("$.id").isEqualTo(expectedId)
coVerify {
someService.save(expectedToStore)
}
}

coVerify的测试失败,因为startDate不匹配:

Verification failed: ...
... arguments are not matching:
[0]: argument: SomeEntity(id=null, startDate=2021-04-22T22:00Z),
matcher: eq(SomeEntity(id=null, startDate=2021-04-23T00:00+02:00)),
result: -

在语义上,startDate是匹配的,但是时区不同。我想知道如何强制coVerify使用OffsetDateTime类型的适当语义比较,或者如何强制OffsetDateTime=的内部格式?或者我们应该使用什么其他方法来验证expectedToStore值是否传递给someService.save(...)?

我可以使用withArgs,但它很麻烦:

coVerify {
someService.save(withArg {   
assertThat(it.startDate).isEqualTo(expectedToStore.startDate)
// other manual asserts
})
}

br

添加到你的application.properties:

spring.jackson.deserialization.adjust-dates-to-context-time-zone=false

这样,偏移量将在检索时被反序列化,而不会被更改。


我在GitHub上创建了一个(稍微修改的)复制存储库。在控制器内部,dto.startDate的值已经是2021-04-22T22:00Z,因此在UTC。

默认情况下,序列化库使用"Jackson"将反序列化期间的所有偏移量对齐到相同的配置偏移量。默认使用的偏移量是+00:00Z,类似于UTC。

您可以通过spring.jackson.deserialization.adjust-dates-to-context-time-zone={true false}属性启用/禁用此行为,并使用spring.jackson.time-zone=<timezone>设置时区

或者,您可以在反序列化期间强制将偏移量与其他时区对齐:

spring.jackson.time-zone=Europe/Berlin

这样,偏移量将与时区Europe/Berlin对齐。

最新更新