I have a function under test that takes an `Iterab...
# strikt
r
I have a function under test that takes an
Iterable<T>
and returns a subset of that given a single element
T
. For example, assume my function has signature
fun <T> Iterable<T>.priorAdjacent(elem: T): List<T>
. Currently use the pattern:
expectThat(elems) { get { priorAdjacent(elems[3]) } isEqualTo elems.slice(1..2) }
which reads nicely and produces understandable failure messages. That being said, is that the best approach?
r
Yes, basically. You could always define an extension function if it’s something you use repeatedly
Copy code
fun <T> Assertion.Builder<Iterable<T>>.priorAdjacent(elem: T): Assertion.Builder<List<T>> =
  get { priorAdjacent(elem) }
👍 1
then you could write the assertion as
Copy code
expectThat(elems)
  .priorAdjacent(elems[3])
  .isEqualTo(elems.slice(1..2))
c
interesting, I always try to have everything that can possibly fail in the expectThat(…) part, and use get() only to navigate the result
never thought of expectThat(subject).get{ testedMethod}
r
Yeah, I was assuming in this case that wasn’t really the point of the test, but maybe I misunderstood
r
The
priorAdjacent
is the function under test yes. So this isn't idiomatic then?
I thought
expectThat(subject)
was the expected way to use Strikt. No pun intended 🙂
c
the typical way is to do call the method under test before and use strikt for the asserting, but maybe thats not the only good way to use it…
r
Yeah, what's nice about this style is that the failure message is "complete" -- it shows the input, the functions performed on it, the actual and expected output.
Examples:
Copy code
▼ Expect that [Elem(idx=0), Elem(idx=1), Elem(idx=2)]:
  ▼ priorAdjacent(elems[1], ::isAdjacent):
    ✗ is equal to []
            found [Elem(idx=0)]
vs
Copy code
▼ Expect that [Elem(idx=0)]:
  ✗ is equal to []
          found [Elem(idx=0)]
The only way to make sense of the latter message is via its context in the test code.
r
Another way would be
Copy code
expectCatching {
  elems.priorAdjacent(elems[3])
}
  .isSuccess()
  .isEqualTo(elems.slice(1..2))
r
I suppose the advantage of that is that it handles exceptions with a nicer test failure, but it still relies on context to know which element is actually failing:
Copy code
▼ Expect that Success([Elem(idx=0), Elem(idx=1), Elem(idx=2)]):
  ✓ is success
  ▼ value:
    ✗ is equal to [Elem(idx=1), Elem(idx=2)]
            found [Elem(idx=0), Elem(idx=1), Elem(idx=2)]
c
maybe there could be an alias to get thats nicer suited for this use case. maybe
call
?
👍 1