Way back when (20th October 08 to be precise) whilst at iMeta I blogged about extending the exception testing capabilities in NUnit, using a little homebrew class that I then carried with me everywhere.
The basic problem the class solved was of imprecision in asserting the source of exceptions using the [ExpectedException] attribute:
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void DoStuff_Throws_ArgumentNullException_For_Null_Argument()
{
// arrange
var myObj = new VolatileObject(null);
// act
myObj.DoesStuff(null);
}
public class VolatileObject
{
public VolatileObject(object ctor)
{
if (ctor == null) throw new ArgumentNullException("ctor");
}
public void DoesStuff(object parameterName)
{
if (parameterName == null) throw new ArgumentNullException("parameterName");
}
}
If the VolatileObject constructor call throws ArgumentNullException (as it will, we’re passing null), the test will pass. That’s not what we’re testing, we’re testing that a call DoStuff with null throws an ArgumentNullException (hence the test name of DoStuff_Throws_ArgumentNullException_For_Null_Argument(). The attribute approach is too coarse grained. As I said, I used to use my own class, but since picking up Fluent Assertions I’m naturally using their implementation, either way the approach is the same, focus down the scope for thrown exceptions:
[Test]
public void DoStuff_Throws_ArgumentNullException_For_Null_Argument()
{
var myObj = new VolatileObject(null);
Action act = () => myObj.DoesStuff(null);
act.ShouldThrow().WithMessage("parameterName", ComparisonMode.Substring);
}
Notice that we’re focusing the assertion around just the call that should result in an exception (the Action act). Additionally we can make assertions about the the message of the exception, is this case making sure the correct parameter name shows up using a Substring comparison.
Of course we’re still passing null to the constructor, so the test now fails! Just as it should have done before. Chuck anything into the constructor and the test now passes when DoesStuff throws an exception.
I’ve been using Fluent Assertions a lot to simplify the expression of my assertions:
[Test]
public void Stuff_Should()
{
string.Empty.Should().NotBeNull();
string.Empty.Should().HaveLength(0);
((object)null).Should().BeNull();
"1234".Should().Be("1234");
100.Should().NotBe(99);
DateTime.Now.Should().BeAfter(new DateTime(1900, 1, 1));
Colors.Red.Should().NotBe(Colors.Green);
(-1).Should().BeLessThan(0);
1.Should().BeGreaterThan(0);
}
How straightforward is that? Even better – should a condition fail, you’ve given Fluent Assertions more than enough information to provide a neat explanation of the failure and the conditions.
Like this:
Be the first to like this post.