MorningLightMountain

a little something from an immotile

Posts Tagged ‘Unit testing’

Timing integration tests

Posted by Dan G on November 30, 2011

Once more Fluent Assertions has come in handy for providing a simple way of asserting the execution time of an Action (in this case a big bit of data formatting), buried away almost as foot note on their docs page is:

New in version 1.4 is a method to assert that the execution time of particular method or action does not exceed a predefined value. To verify the execution time of a method, use the following syntax:

var subject = new SomePotentiallyVerySlowClass(); 
subject.ExecutionTimeOf(s => s.ExpensiveMethod()).ShouldNotExceed(500.Milliseconds());


Alternatively, to verify the execution time of an arbitrary action, use this syntax:

Action someAction = () => Thread.Sleep(510); 
someAction.ExecutionTime().ShouldNotExceed(100.Milliseconds());


Since it doesn’t make sense to do something like that in Silverlight, it is only available in the .NET 3.5 and .NET 4.0 versions of Fluent Assertions.

Make sure to set a sensible execution limit – bear in mind who’s running the tests (might be slow hardware – false negatives ahoy). It’s considered polite to put a Category attribute with a “Slow” value so people can exclude long running integration tests.

Posted in Tools | Tagged: , , , | Leave a Comment »

Fluent Assertions and exception testing

Posted by Dan G on November 12, 2011

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.

Posted in Good practie | Tagged: , , , | 1 Comment »

 
Follow

Get every new post delivered to your Inbox.

Join 165 other followers