Tailoring a custom matcher for NMock

You’ll often hear proponents of test-driven development claim that unit testing is hard and that it forces them to open up their classes’ hidden logic for them to be testable. That might be true to some degree, but more often in my opinion you’ll find that designing your system to be testable also has the nifty side-effect of separating your logic into .. umm logical chunks… and what I really mean here is that your chunks have a tendency to become orthogonal, which is by far one of the best quality attributes of a system.

BUT that was not what I was going to say, actually – I just wanted to comment on a nifty thing, I recently found out: implementing my own Matcher to use with NMock.

An NMock Matcher is an abstract class, which requires you to implement the following members:

A matcher can be used in the call to With(...) when stubbing or expecting… an example could be setting an expectation that a search function on our user repository will return an empty result… like so:

In the example above, Is is a class containing a static method StringContatining, which returns a matcher of a certain type. Now, when the test runs, and NMock needs to decide if an intercepted function call matches the expectation above, it will iterate though the given matchers, and call their Matches function, passing to it the actual argument as object o.

The matcher returned by StringContaining probably contains an implementation of Matches which looks something like this:

where _substring was probably set in the ctor of the matcher when it was constructed by the StringContaining function.

Now that leads me to my recent problem: I needed to pull out the actual argument given when the expected function call was performed. In my case the argument was a delegate, which I wanted to pull out, and then invoke it a few times with different arguments.

What I did was this:

This allows me to set up an expectation like this:

Now, after the code has been run, I have access to the delegate passed to the file service through snatcher.Object.

If someone knows a cooler way to do this, please do post a comment below. Until then, I will continue to think that it was actually pretty nifty.

How to configure NHaml

Ever wanted to use your own custom HtmlHelper extensions inside your NHaml views? I wanted that, but I got this error:

error CS1061: ‘System.Web.Mvc.HtmlHelper’ does not contain a definition for ‘WhyOhWhy’ and no extension method ‘WhyOhWhy’ accepting a first argument of type ‘System.Web.Mvc.HtmlHelper’ could be found (are you missing a using directive or an assembly reference?)

The problem was that NHaml would not know that there existed some extensions of the HtmlHelper class in some obscure assembly somewhere inside my web app. To do this, you need to tell NHaml exactly which assembly and which namespaces to include in its search. Here is how to do it:

In your web.config, beneath the <configSections> node, add this

– and then outside of <configSections>, add this:

This will cause NHaml.config to be included. We could just have embedded the configuration inside the web.config file, but we want to make separate NHaml.config files for each environment we want to deploy our application in. Then we can turn on NHaml’s compiled view caching feature by flicking the production attribute.

An example NHaml configuration is something like this:

Suddenly you will gain access to everything inside the specified namespaces inside your NHaml templates. Nifty!

Using compression at field level when persisting

One day at work, someone needed to store a lot of text in a field of a domain object – and since we are using NHibernate for persistence, that field would get stored to the database, taking up a huge amount of space.

To circumvent this, we just made the actual type of the member variable description be a byte[], and then we let the accessor property Description zip and unzip when accessing the value.

Like so:

It should be noted that it is crucial that the ToArray() method of the compressed MemoryStream be called after the GZipStream stream has been disposed! That’s because the GZipStream will not write the gzip stream footer bytes until the stream is disposed. So if ToArray() is called before disposing, you will get an incomplete stream of bytes.

Moreover it should be noted that zipping strings in the database is not always cool because:

  1. Compression kicks in for strings at around 2-300 chars. The size of the compressed data is greater than that of the original string for shorter strings.
  2. Querying is impossible/hard/weird. 🙂

But it is a nifty little trick to put in one’s backpack, and I had all sorts of trouble figuring out exactly how to make the GZipStream behave, so I figured it would be nice to put a working example on the net.