I build web application using Kotlin and Spring Boot, I use MockMvc to write integration test.
I'm not satisfied how assertion looks like, here is typical assertion:
@Test
fun `Get profile by id`() {
thereIsATeacher(lissaSkipper)
mockMvc.get("/teacher/{id}", "52058608")
.andExpect {
status { isOk() }
jsonPath("$.id") { value("52058608") }
jsonPath("$.slug") { value("lissa-skipper-math-teacher") }
}
}
the jsonPath("$.id") { value("52058608") }
, for me, is not good enough, but it's very popular.
I spent a few hours and tried to build "domain assertion", using DSL. Now the test looks:
@Test
fun `Get profile by id`() {
thereIsATeacher(lissaSkipper)
mockMvc.get("/teacher/{id}", "52058608")
.andExpect {
status { isOk() }
teacherProfile {
id("52058608")
slug("lissa-skipper-math-teacher")
profilePhoto {
url("https://example.com/photo.jpg")
alt("Lissa Skipper - math teacher")
}
joined("2023-01-22T10:00:00Z")
}
}
}
and here are assertion classes
class TeacherProfileRestAssertion internal constructor(private val dsl: MockMvcResultMatchersDsl) {
fun id(expectedValue: String) {
dsl.jsonPath("$.id") { value(expectedValue) }
}
fun slug(expectedValue: String) {
dsl.jsonPath("$.slug") { value(expectedValue) }
}
fun profilePhoto(imageAssertion: ImageRestAssertion.() -> Unit) {
ImageRestAssertion(dsl, "$.profilePhoto").apply(imageAssertion)
}
// ...
}
fun MockMvcResultMatchersDsl.teacherProfile(assertion: TeacherProfileRestAssertion.() -> Unit) {
TeacherProfileRestAssertion(this).apply(assertion)
}
class ImageRestAssertion internal constructor(
private val dsl: MockMvcResultMatchersDsl,
private val jsonPrefix: String = "$"
) {
fun url(expectedValue: String) {
dsl.jsonPath("$jsonPrefix.url") { value(expectedValue) }
}
//....
}
What do you think? It's a good idea to hide jsonPaths
behins such dsl assertions?