【发布时间】:2021-12-13 21:05:04
【问题描述】:
我在 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: -
在语义上,startDates 匹配,但时区不同。我想知道如何强制coVerify 对OffsetDateTime 类型使用适当的语义比较,或者如何强制OffsetDateTime= 的内部格式?或者我们应该使用什么其他方法来验证 expectedToStore 值是否传递给 someService.save(...) ?
我可以使用withArgs,但它很麻烦:
coVerify {
someService.save(withArg {
assertThat(it.startDate).isEqualTo(expectedToStore.startDate)
// other manual asserts
})
}
【问题讨论】:
-
您能添加您要测试的代码吗?谢谢!
-
@JoãoDias 我添加了正在测试的(琐碎的)控制器代码,还添加了
withArgs解决方法,这仍然太麻烦了 -
@Stuck 我试图让最小的复制运行,但您的代码中的某些内容没有对齐。您的
toEntity函数需要一个不可为空的Long并且没有默认值,但是在您的实现和测试中,您没有将任何值作为参数传递。此外,该函数根本不使用参数userId。你会这么好心,把代码调整成可运行的吗?
标签: spring spring-boot kotlin spring-mvc mockk