https://kotlinlang.org logo
#kotest
Title
# kotest
a

André Martins

04/01/2022, 9:14 AM
Hey when generating an arbitrary domain model instance how can one lock some properties? Suppose I have a Student data class with an id, number, name and some other fields. If I have the following generator
Copy code
fun Arb.Companion.student(): Arb<Student> = arbitrary { rs ->
    Student(
        id = Arb.uuid(V4,false).next(rs)
        name = Arb.string().next(rs),
        number = <http://Arb.int|Arb.int>().next(rs), ...
    )
}
What can I add here to lock the number I which my generated student have?
Copy code
Arb.student().<here>?
// Something like
Arb.student().with(number, 123)
Anyway I can do this?
e

Emil Kantis

04/01/2022, 9:17 AM
Arb.student().copy(number = 123)
perhaps?
a

André Martins

04/01/2022, 9:18 AM
I need to call next first, but that way I’m generating a random of everything and then locking it
I’ve seen this in other frameworks wasn’t sure if for kotlin thats the way to go
p

phldavies

04/01/2022, 9:32 AM
I’ve been taking the approach similar to this:
Copy code
fun Arb.Companion.student(
    idArb: Arb<UUID> = uuid(V4, false),
    nameArb: Arb<String> = string(),
    numberArb: Arb<Int> = int()
): Arb<Student> = arbitrary {
    Student(
        id = idArb.bind(),
        name = nameArb.bind(),
        number = numberArb.bind(),
    )
}

val myStudent = Arb.student(numberArb = Arb.constant(123)).single()
which also allows for more control over fields than just locking in values:
Copy code
val namedStudent = Arb.student(nameArb = Arb.name().map { (first, last) -> "$last, $first" }).single()
a

André Martins

04/01/2022, 9:34 AM
ya seems nice!
p

phldavies

04/01/2022, 9:36 AM
Also, personal preference maybe, but I’ve been adding these arbitraries onto my domain model companions rather than onto
Arb
, i.e.
Copy code
fun Student.Companion.arbitrary(...) = ...
allowing for
Copy code
Student.arbitrary()
rather than
Copy code
Arb.student()
It’s just kept
Arb
a little cleaner as base arbitraries
👍 1
👍🏻 1
a

André Martins

04/01/2022, 9:37 AM
thx for the suggestions 😄
e

Emil Kantis

04/01/2022, 9:39 AM
In case the type is unique, you could also use
Arb.data<Student>(mapOf(Int::class to Arb.constant(123))
to generate the entire thing.. 🙂
Arb.data<Student>()
will create your first exmaple there, though I’m unsure if uuid binding will work without adding it explicitly.. Phil’s approach gives nice flexibility from use sites though, gonna try that out myself 🙂
😄 1
a

André Martins

04/01/2022, 9:41 AM
Ya I’ve seen that with bind too
l

LeoColman

04/01/2022, 6:31 PM
I think you could also map an arb
Copy code
Arb.student().map { it.copy(number = 123) }
24 Views