I’m starting using Fluent Assertions and I like it a lot, but wonder if it’s possible to extend the existing tests in a general way like this:
- add method
hasSizeAtLeast(int limit)inGroupAssert - add method
startsWithIgnoringCase(String prefix)inStringAssert - use alternatives like
x.either().isIn(someSet).or().isNull()
These are just examples what I could need soon. I can do some workaround for each of them, but then I lose the readability and the easy of use of the fluent interface.
My last example is meant to throw iff both x.isIn(someSet) and x.isNull() do.
Here is a post by the author about opening up his API for extending assertions on already handled types. Lesson #1 in particular discusses the change to un-finalize classes. The post also gives an example of sub-classing
StringAssertasMyStringAssert.However, it looks like you cannot extend classes such as
StringAssertin a way that maintains the “fluency” of the API. TheStringAssertclass isn’t final, but still it doesn’t allow you to parameterize its type (i.e. the “this” type that’s returned by methods inStringAssertitself) in subclasses. For example, let’s say you add a methodcheckFooinMyStringAssert. As you discovered, the following is invalid because the originalStringAssertmethods returnStringAssert:You only can call your subclass’s methods first, which is valid but kind of lame:
You might consider contacting the author, or even submitting a patch to his git project. A possible solution would be to add the parameterized type back into
StringAssert, and also provide theStringAssertconcrete type via an anonymous subclass withinAssertions.assertThat(String), which is the recommended entry point anyway. Then, everybody else can subclassStringAssertas you described. I haven’t tested this suggestion either, but it seems to make sense…