How do people tend to unit test DSL functions like the
address
function below? What are some good practices to handle the
Address.Builder
dependency?
Copy code
fun main() {
val address = address {
street = "123 Any St."
city = "Any city"
}
println(address)
}
fun address(lambda: Address.Builder.() -> Unit): Address {
return Address.Builder().apply(lambda).build()
}
data class Address(
val street: String,
val city: String
) {
class Builder {
var street: String? = null
var city: String? = null
fun build(): Address {
return Address(street!!, city!!)
}
}
}
j
jbnizet
01/17/2021, 4:34 PM
Use the DSL in your tests just like a real user of the DSL would, and check it does what it’s expected to do:
Copy code
class AddressDslTest {
@Test
fun `should allow creating an address`() {
val result = address {
street = "Downing street"
city = "London"
}
assertEquals(Address("Downing street", "London"), result)
}
}
☝️ 1
jbnizet
01/17/2021, 4:35 PM
Adding a test where you forget to set the street or the city should give you ideas about how you could improve the code.
s
Scott Whitman
01/17/2021, 4:47 PM
How about when the DSL is nested? Another example, to unit test this
person
DSL function, It seems I would need to have
home
and
address
in my
person
unit tests.
Copy code
person {
home {
address {
...
}
...
}
...
}
j
jbnizet
01/17/2021, 6:03 PM
I don’t se any reason not to apply the same principle.
m
Matteo Mirk
01/18/2021, 11:34 AM
it’s the same: just check the built object has the expected values, and you’ll test the builder indirectly