Let's say I have a following data structure in Kotlin (simplified from the actual need):
data class RootClass(
val a: String,
val nestedContent: MiddleClass,
) : Result
data class MiddleClass(
val foo: String,
val leaf: Leaf,
)
data class Leaf(
val value: String,
val leaf: Leaf?,
)
For purpose of assertion/verification in tests, is there some way (with e.g. some library) to define the expected result in a declarative way, allowing e.g. ignoring arbitrary fields. So that the expected result could be presented somewhat in the following way
RootClass(
a = "Foo",
nestedContent = MiddleClass(
foo = anyString(),
leaf = Leaf(
value = "leaf-value",
leaf = any(Leaf)
)
)
)
I've looked a bit into assertK, Hamcrest and mockK matchers, etc. not very deep yet but didn't find "an optimal way" yet. For typical use cases it's usually possible to e.g. create custom helpers that check the wanted fields but testing against something like above would be occasionally useful + easy to read.
UPDATE: Having the expected result "as such" would be useful for "specification by example" kind of usage.
The type safe builders pattern is very useful if you want to be declarative.
First, declare an interface that represents a matcher.
Then you can create all kinds of implementations for this (see the various matchers available in Hamcrest for example). For now, I'll just have these simple ones:
Then we can write a builder that builds a new kind of matcher, that matches only if the list of
Matcher<T>s it contains all match.With just that, we can already create a
Matcher<RootClass>like the one in your question:With some tweaking with the names, you can make this more readable.
As an extension, here I added an
AnyMatcher: