I haven’t been using Spark for quite some time, but - really…?!
Sure… The question just is how to tackle this.
Since I brought up the macro approach, I’ve tinkered a bit with it, and I’m not that convinced. The remaining issues with the
mkPropEqMatcher convenience method approach is that the type inference requires guidance (i.e.
(_: Book)) and the property name must be supplied. I haven’t found a nice way around the first issue in general, so that only leaves room for improvement regarding the property name.
I have come up with a naive, quickhack
haveEq() macro that extracts the property name for the common case of chained accessors, just matching on
Select instances in the tree and its qualifiers, recursively. (Disclaimer: I’m not fluent with macros at all.)
book should have(
haveEq((_: Book).title)("Moby Dick"),
This yields ‘The author.firstName property had value “Hermann”, instead of its expected value “Herman”, […]’. However, a property match like
haveEq((_: Book).toString)("") would give you ‘The <unknown> property had value […]’… Not sure that’s worth the effort and a huge improvement over
book should have(
mkPropEqMatcher("title", (_: Book).title)("Moby Dick"),
mkPropEqMatcher("author first name", (_: Book).author.firstName)("Herman")
Going back to square one, what’s the actual issue you have with
book.title should === ("Moby Dick")
book.author.firstName should === ("Herman")
(book.title, book.author.firstName) should === ("Moby Dick", "Herman")
You mention type safety, so I assume that you’re referring to the leniency of universal equality via
#equals(), as inherited from Java, as in
book.title should === (21). But that’s an issue that probably affects your whole code base, not just the tests. By buying into the cats ecosystem, for example, and relying on
Eq rather than
#equals(), you could make the above variants type safe by pulling in StrictCatsEquality.
(There’s other libraries providing similar abstractions, and there’s other approaches to type safe equality comparisons, e.g. the SuperSafe plugin.)
To sum up, I’m not sure that Scalatest’s
have construct is an ideal approach to type safe (equality) assertions - even more, if one feels seduced to bikeshed it further. It may have its place, but I think its applicability is somewhat limited. (And I’ve learned some new stuff when playing with this question, so it still feels like well-spent time.)