How do people tend to unit test DSL functions like...
# getting-started
s
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
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
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
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
I don’t se any reason not to apply the same principle.
m
it’s the same: just check the built object has the expected values, and you’ll test the builder indirectly