Home > Unit Testing > Nice up those Assertions with Shouldly!

Nice up those Assertions with Shouldly!

One thing I noticed while having a play with Ruby was that the syntax for their testing tools is quite a lot more natural-language like and easier to read – here’s an example from an RSpec tutorial:

describe User do
  it "should be in any roles assigned to it" do
    user = User.new
    user.assign_role("assigned role")
    user.should be_in_role("assigned role")
  end
it "should NOT be in any roles not assigned to it" do
    user.should_not be_in_role("unassigned role")
  end
end

Aside from the test name being a string, you can see the actual assertions in the format ‘variable.should be_some_value’, which is kind of more readable than it might be in C#:

Assert.Contains(user, unassignedRoles);

or

Assert.That(unassignedRoles.Contains(user));

Admittedly, the second example is nicer to read – the trouble with that is that you’re checking a true/false result, so the feedback you get from NUnit isn’t great:

Test ‘Access_Tests.TestAddUser’ failed:  Expected: True  But was:  False

Fortunately, there are a few tools coming out for .net now which address this situation in a bit more of a ruby-like way.  The one I’ve been using recently is Shouldly, an open source project on GitHub.

Using Shouldly (which is basically just a wrapper around NUnit and Rhino Mocks), you can go wild with should-style assertions:

age.ShouldBe(3);

family.ShouldContain(“mum”);

greetingMessage.ShouldStartWith(“Sup y’all”);

And so on.  Not bad, not bad, not sure if it’s worth learning another API for though.  However, the real beauty of Shouldly is what you get when an assertion fails.  Instead of an NUnit-style

Expected: 3

But was:  2

– which gives you a clue, but isn’t terribly helpful – you get:

age

should be    3

but was    2

See that small but important difference?  The variable name is there in the failure message, which makes working out what went wrong a fair bit easier – particularly when a test fails that you haven’t seen for a while.

Even more useful is what you get with checking calls in Rhino Mocks.  Instead of calling

fileMover.AssertWasCalled(fm => fm.MoveFile(“test.txt”, “processed\\test.txt”));

and getting a rather ugly and unhelpful

Rhino.Mocks.Exceptions.ExpectationViolationException : IFileMover.MoveFile(“test.txt”, “processed\test.txt”); Expected #1, Actual #0.

With Shouldly, you call

fileMover.ShouldHaveBeenCalled(fm => fm.MoveFile(“test.txt”, “processed\\test.txt”));

and end up with

*Expecting*

MoveFile(“test.txt”, “processed\test.txt”)

*Recorded*

0: MoveFile(“test1.txt”, “unprocessed\test1.txt”)

1: MoveFile(“test2.txt”, “unprocessed\test2.txt”)

As you can see, it’s not only much more obvious what’s happening, but you actually get a list of all of the calls that were made on the mock object, including parameters!  That’s about half my unit test debugging gone right there.  Sweet!

Shouldly isn’t a 1.0 yet, and still has some missing functionality, but I’d already find it hard to work without it.  And it’s open source, so get yourself on GitHub, fork a branch, and see if you can make my life even easier!

Advertisements
  1. No comments yet.
  1. March 29, 2011 at 4:36 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: