Archive for the ‘Software Development’ Category.

Moq Sequences

I have recently started to use Moq for mocking and I really like it. The fluent interface and Lambda support makes it very easy and natural to use.

However, I quickly ran into a situation where I wanted to ensure that methods on a mock object were called in a particular order. I have provided a simpler example below where I want to check that BlogPresenter.Show() shows blogs in reverse chronological order:

public class Post
{
    public DateTime DateTime { get; set; }
}

public class BlogPresenter
{
    private readonly BlogView view;

    public BlogPresenter(BlogView view)
    {
        this.view = view;
    }

    public void Show(IEnumerable posts)
    {
        foreach (var post in posts.OrderByDescending(post => post.DateTime))
            view.ShowPost(post);
    }
}

public interface BlogView
{
    void ShowPost(Post post);
}

To check this I used a callback to increment a counter like this:

[Test]
public void Should_show_each_post_once_with_most_recent_first()
{
    var olderPost = new Post { DateTime = new DateTime(2010, 1, 1) };
    var newerPost = new Post { DateTime = new DateTime(2010, 1, 2) };
    var posts = new List { newerPost, olderPost };

    var mockView = new Mock();

    var viewOrder = 0;

    mockView.Setup(v => v.ShowPost(newerPost)).Callback(() => Assert.That(viewOrder++, Is.EqualTo(0)));
    mockView.Setup(v => v.ShowPost(olderPost)).Callback(() => Assert.That(viewOrder++, Is.EqualTo(1)));

    new BlogPresenter(mockView.Object).Show(posts);

    mockView.Verify(v => v.ShowPost(newerPost), Times.Once());
    mockView.Verify(v => v.ShowPost(olderPost), Times.Once());
}

This works code but is not very intentional. I wanted to express the intent the there is a required ordering of method calls. After searching around I found a nice code snippet from Max Guernsey, III that was promising. I thought I would push a little further to see if I could get something like this:

[Test]
public void Should_show_each_post_with_most_recent_first_using_sequences()
{
    var olderPost = new Post { DateTime = new DateTime(2010, 1, 1) };
    var newerPost = new Post { DateTime = new DateTime(2010, 1, 2) };
    var posts = new List { newerPost, olderPost };

    var mockView = new Mock();

    using (Sequence.Create())
    {
        mockView.Setup(v => v.ShowPost(newerPost)).InSequence();
        mockView.Setup(v => v.ShowPost(olderPost)).InSequence();

        new BlogPresenter(mockView.Object).Show(posts);
    }
}

So, I created Moq.Sequences and you download Moq.Sequences.dll from github. Simply, add Moq.Sequences.dll as a reference in your .Net project and add a using Moq.Sequences; in your test class. Moq.Sequences supports the following:

  • checks order of method calls, property gets and property sets
  • allows you to specify the number of times a call is made before the next one is expected
  • allows intermixing of sequenced and non-sequenced expectations
  • thread safe – each thread can have its own sequence

Sequences

Sequences are added using the Sequence static class and extension methods. You create a sequence by calling:

using (Sequence.Create())
{
    ...
}

Sequences that do not fully complete are detected when the sequence is disposed. So, all the setups and mock calls should be done within the lifetime of the sequence.

Steps

Within a sequence you set the expectations for ordering via an extension method InSequence<(). I call these steps. For example,

using (Sequence.Create())
{
    mock.Setup(_ => _.Method1()).InSequence();
    mock.Setup(_ => _.Method2()).InSequence();
    ...
}

This sets an expectation that Method1() will be called once followed by a single call to Method2. You can set more sophisticated expectations by using a Times parameter:

using (Sequence.Create())
{
    mock.Setup(_ => _.Method1()).InSequence(Times.AtMostOnce());
    mock.Setup(_ => _.Method2()).InSequence(Times.Between(1, 10, Range.Inclusive));
    ...
}

Steps can be created for method calls, property gets and property sets:

using (Sequence.Create())
{
    mock.Setup(_ => _.Method1()).InSequence(); // method call
    mock.SetupGet(_ => _.Property1).InSequence().Returns(0);  // property get
    mock.SetupSet(_ => _.Property2 = 0).InSequence(); // property set
    ...
}

Also, sequenced steps can be intermingled with non-sequenced expectations.

Loops

Loops are used when you want to check that as group of method calls are called in order several times. An example of this could be some resources which you expect to be opened, operated on and then closed, one after the other.

Loops are created via Sequence.Loop():

using (Sequence.Create())
{
    mock.Setup(_ => _.Method1()).InSequence();

    using (Sequence.Loop())
    {
        mock.Setup(_ => _.Method2()).InSequence();
        mock.Setup(_ => _.Method3()).InSequence();
    }
    ...
}

The above checks that Method1 is called by any number of calls to Method2 followed immediately by a call to Method3. You can constrain the number of times the loop can be executed by adding a Times parameter such as the following example where the combination of Method2 and Method3 should be called exactly twice:

using (Sequence.Create())
{
    mock.Setup(_ => _.Method1()).InSequence();

    using (Sequence.Loop(Times.Exactly(2)))
    {
        mock.Setup(_ => _.Method2()).InSequence();
        mock.Setup(_ => _.Method3()).InSequence();
    }
    ...
}

Wrap-Up

Moq.Sequences provides a simple, intentional way of checking that things are are done in a specific order. Feel free to check it out at github. I welcome any feedback!

PostRank – A .NET API for AideRSS PostRank

AideRSS provides a service that ranks online content such as RSS feeds, blog posts and so on. I have always been impressed with AideRSS and wanted to educate myself with writing REST interface logic, ASP.Net and Web 2.0 in general. AideRSS also provides a PostRank API to their service so I decided to write a .NET client wrapper for this API to make it easier to use. You can download the API including source and binaries from here:

Downloadpostrank-10.zip

Why Did I Write This?

My goal with the API beyond learning some new stuff was to leverage TDD and allow emergent design to surface an underlying domain model. I wanted to avoid a simple static functional wrapper for the API and instead provide a design that would allow more powerful usages of the PostRank API. I wanted TDD to help evolve a reasonable domain model which would include classes to represent feeds, posts and so on. To do this I systematically applied the XP rules of simplicity:

  1. Testable – has a test
  2. Communicative – classes and methods are intent revealing
  3. Factored – no duplication of logic or structure
  4. Minimal – minimum number of classes and methods

While I am not an expert on RSS or the PostRank API I am quite happy with the resulting API. The classes that emerged make sense, at least to me! There is also a safety net of 105 unit tests that I can use for future refactoring and enhancements.

What Does it Do?

The API provides full access to the underlying PostRank API. Besides creating unit tests for the code I also included a demo command line application and a demo ASP.Net project.

The demo command line program takes a single command line argument which is the RSS feed you are interested in and defaults to Ilya Grigorik’s blog:

PostRank Command Line Output

The ASP.Net project provides an interactive UI allowing you to enter an RSS feed and see AideRSS PostRank features such as top posts in a given time period. The screen shots below show some of the features of the API:

Top Posts of the Year Top Posts of the Month Great Posts

Note that there is an alternate .NET API written by William Spaetzel that you can get from http://spaetzel.com/postranksharp.

I welcome any feedback you may have on this API.

Taking Stock of Your Software Inventory

Do you have inventory piling up between your development team and QA?

This inventory of unconfirmed functionality limits your team’s agility on a few fronts:

  • your software is not always potentially shippable
  • deferred ROI
  • delayed feedback from QA

One of the main goals of your agile team is to build potentially shippable releases every iteration. When QA testing is done after development releases your team can no longer achieve this goal.

This deferred testing also creates an inventory of unconfirmed features that need to be managed. And just like any manufacturing system, inventory is wasteful and costs your company time and money. Every day that your software is not shipped decreases the ROI.

The longer your software remains untested the more costly any corrective action becomes. The cost arises from many factors including the ramp-up time for the developers, context-switching time, overhead with issue tracking and so on.

Finally, feedback from good testers is invaluable. They think differently from developers and tend to have a more outward-looking customer perspective. If you get this feedback earlier in the process you will see a reduction in defects and less rework.

If you find your team in this situation here are a few things you could might consider doing:

Track Metrics

Select metrics such as defect counts or time to close that you feel best highlights the obstacles your team faces. Chart these metrics in big visible charts

Consider translating technical metrics into bottom-line financial data. For example, you could use daily expected revenue of the product to calculate the revenue loss due to each day of delay.

Get Developers and Testers Working Together

There has been much talk about getting quality assurance infused throughout the product cycle. Agile teams are tailor-made for this transition. Get a tester on your team and allow her to contribute throughout the iterationAside from traditional testing, the tester can bullet-proof the story tests, suggest testing tasks, pair with developers on testing and so on

This inter-personal contact will do more to promote quality within your team than any formal QA process ever will.

Stagger Iteration Testing

Staggered testing

If you must maintain a separate system test phase, consider having the QA team test the previous iterations release. This way, the QA team has a stable release for testing and feedback is delayed at most one iteration

Over time, you may be able to move additional QA activities into the development iteration.