Implementing Progressive Inner Closure Pattern in C#. 3. Interaction Testing


No one would believe that, in this blog, throwing a bunch of unit tests to explore or verify some simple behaviour makes a post deserving a “Unit Testing” tag, right? ;-p

We proved that we could achieve the same (or higher) level of functionality with a progressive inner closure, but we also saw it comes with a cost: slightly more complex logic. But we left out another cost, that, in my opinion, is way greater. As big it is that I would not consider going down this road if we could not “pay” that cost cheaply.
That cost is ease of testing.

The FluentWriter class we created makes a perfect collaborator: simple and focused, which, in geeky jargon, reads cohesive. A lot of classes in our system would use this collaborator in order to write urls.
I am a an of learning by example, so let’s show a simple collaborator that will use the writer. Let’s imagine a class that transforms a given domain entity to its representation on a screen. This mapper might get a complete entity as an input and would output a transformed one with only some of the properties (ready for displaying), which will include the url to the entity being displayed:

When testing this class we really do not need to test if the url to the entity was written correctly, as we already tested those features when FluentWriter was itself tested. We all heard that depending upon abstractions makes you look more handsome and do not get me started with the whole business of becoming blind when we depend upon implementations. I like my eyesight as it is so I will introduce a simple interface:

The test case will only prove that the properties of the mapped dto are set with the right formatting. But we have a problem with the Url property, as it depends on the collaborator behaviour. A testing double (an stub in this case) comes to the rescue. My personal favourite when it comes to tests doubles is RhinoMocks, so that I will use:

Happy and satisfied with our cleverness, we run the test getting a disappointing:

What?!? It turns out we created a problems to ourselves by allowing an anonymous method in our API as Rhinomocks is unable to figure out that the delegate we pass represents the same action as the one in the production code. a cheap workaround would be ignoring the argument with

…but we would be regretting this move if we made a mistake calling the right method of the writer, as no test would fail.

What to do? Squeezing our brains is always an option.
If no framework helps us, we still have good old manual mocks. If only we could create a double that allowed getting in the middle of the method chaining… Hey!! Wait!! We can! And is cheap! And easy! The only “dirty” thing we are allowing ourselves is relying on IEnd’s Segments property. But that assumption is pretty safe as it is based upon an stable (geeky jargon) interface.
The main trick here is the creation of an interface just for testing purposes that groups all the interfaces from the progressive interface.

And how do we use it? Create an instance and use it as an implementation of IUrlWriter:

It seems easy. Good news is… it is that easy.
But if the reader remembers my previous post, and I would be flattered if they did, I was advocating making tests fail in order to double-check we were not being over-permissive and get a taste of what a failure looks like.
Fine with me taking my own medicine, here is the failing test:

And its output:

Yikes!!! a NullReferenceException? But what does it mean? Well. It turns out that the behaviour of stubs is returning a default value when no expectation is fulfilled, and since the expectation to return an IArea was not fulfilled, a beautiful null was returned, which made the .Entity() invocation throw.

It only sort of works. This technique fails when it needs to fail, but it does not stick to my preaches of making failure descriptive. So I better be searching a better way, as I guess is too late for a rollback to my preaching.
But this is already a pretty lengthy post and I need to create expectation to the next post.

Again, code is available in GoogleCodeGithub.