該賞金過期5天。回答這個問題有資格獲得 50聲望獎勵。 Stuck想引起更多人對這個問題的關注。
我在 DTO 和物體中有一個屬性,定義如下:
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: -
Semantically, the startDates match, but the timezone is different. I wonder how I can enforce coVerify to either use a proper semantic comparison for type OffsetDateTime or how I can enforce the internal format of OffsetDateTime=? Or what other approach should we use to verify the expectedToStore value is passed to someService.save(...) ?
I could use withArgs but it is cumbersome:
coVerify {
someService.save(withArg {
assertThat(it.startDate).isEqualTo(expectedToStore.startDate)
// other manual asserts
})
}
uj5u.com熱心網友回復:
tl;博士
將此添加到您的application.properties:
spring.jackson.deserialization.adjust-dates-to-context-time-zone=false
這樣,偏移量將在檢索時反序列化而不是更改。
我在 GitHub 上創建了一個(稍作修改的)復制存盤庫。在控制器內部, 的值dto.startDate已經是2021-04-22T22:00Z,因此是 UTC。
默認情況下,使用“Jackson”的序列化庫將反序列化期間的所有偏移量對齊到相同的配置偏移量。使用的默認偏移量是 00:00or Z,類似于 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。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/361840.html
標籤:spring spring-boot kotlin spring-mvc mockk
