AutoMockingContainer: Now on Silverlight 4.0

The #Fellows AutoMockingContainer (AMC) which I recently introduced, is now available on Silverlight 4.0.  There have been no code changes, but the the assemblies have been compiled against the SL 4 assemblies and Rhino Mocks 3.5 for Silverlight.  Get the binaries from the link below and source code from the Bitbucket repo.

SharpFellows.AutoMockingContainer.Silverlight.dll (13.50 kb)

NBehave, Dates and value conversions

Some of the guys at my work are starting to get into NBehave in a big way and today asked me an interesting question around how NBehave captures parameter values out of scenarios.  Consider these methods:

[Given("a user has logged on as $username")}
public void SetupUser(string username) { }

[When("the user asks for all blog posts since $fromdate")
public void LoadBlogPostsSince(DateTime fromdate) { }

[Then("they should see $num blog posts")]
public void CheckNumberOfBlogPosts(int num) { }

[BTW please refer to my previous post for an explanation of how methods like this can be invoked by NBehave, if you aren’t familiar with it]

Now you’ll notice that each of these methods capture a parameter value from the scenario.  So if we were to invoke these methods against the following:

Given a user has logged on as Bob
When the user asks for all blog posts since 24/05/2010
Then they should see 15 blog posts

Then the captured parameter values (on my system!) would be “Bob”, “24-May-2010” and “15”.  This is all quite simple, except for the fact that our method parameters are strongly typed and hence some conversion is required.  My colleague was specifically asking about the handling of dates and how NBehave parses it.

NBehave actually calls System.Convert.ChangeType to perform the conversion.  This is a pretty general function which relies heavily on the IConvertible interface to do the hard work.  Curiously, I didn’t actually know that this method existed until I looked into the NBehave code!  But anyway, this method relies on the current thread culture for date parsing.  And this means that the above scenario will not run for a thread running under en-US (since “24/05/2010” is not a valid date in that culture) but will run and yield the expected results on a thread running under en-GB.

June 17 2010

A new AutoMockingContainer (which can work with MEF)

About auto-mocking

The Problem of Dependencies

When working in an Inversion of Control (IOC) container, best practice dictates that you let the IOC do as much work for you as possible and inject your dependencies.  As a rule of thumb, this typically means that classes contain less code and conform better to the Single Responsibility Principle, but they do usually end up with a greater number of dependencies. 

In addition to this. IOC-style coding often uses constructor injection for dependencies which are critical to the functioning of the class and property injection (aka setter injection) for other dependencies (see Martin Fowler for explanation of these terms).

The net result of all this, is that classes often end up with quite a few constructor parameters.  And then when you come to write some unit tests for your classes, you end up having to create and manage a large number of mock objects, even though not all of those may be relevant to your test.

The Solution: Automatically Creating Mocks

And one day some developer decided that this drudge work of creating and managing mock objects could be automated.  In fact, the guys at Eleutian were the first ones to come up with an Auto-Mocking Container (AMC) on the .Net platform … they did it by adding a facility to Castle Windsor.  Since then, AMCs have been added to StructureMap and, more recently, James Broome has produced an AMC for use with Machine.Specifications.  These are great libraries and work well.

And do we need another AMC?

With the notable exception of James’s library, you typically need to take a dependency on an IOC and spin it up in your unit tests.  This is not too much of a problem if your IOC has some support for an AMC.  On my project we are using MEF as an IOC and there isn’t (before now) an AMC that works with that.

The reason I didn’t use James Broome’s library is that Machine.Specifications (aka MSpec) is not really my cup of tea.  I was imprinted with a different BDD framework, NBehave.  James’s library is quite tightly coupled to the MSpec way of working.

Introducing the SharpFellows.AutoMockingContainer

It’s probably best to introduce the #Fellows AMC through some code:

public class BlogViewModel
{
    private IAuthorRepository _authors;
    private ISpamScoringService _spamScoring;

    public BlogViewModel(IAuthorRepository authors, ISpamScoringService spamScoring)
    {
        _authors = authors;
        _spamScoring = spamScoring;
    }

    public void RecordComment(string author, string comment)
    {
        // Do something interesting here
    }
}

[TestClass]
public class BlogViewModelTests
{
    [TestMethod]
    public void TestMethod1()
    {
        // ARRANGE
        var container = new ObjectFactory();
        var viewModel = container.CreateObject<BlogViewModel>();
        var authorName = "author.name";
        var comment = "great stuff";

        // ACT
        viewModel.RecordComment(authorName, comment);

        // ASSERT
        container.GetDependency<IAuthorRepository>()
                 .AssertWasCalled(repo => repo.FindByName(authorName));
        container.GetDependency<ISpamScoringService>()
                 .AssertWasCalled(scoring => scoring.MeasureSpamScore(authorName, comment));
    }
}

As you can see, ObjectFactory is where the good stuff happens.

MEF Support

The #Fellows AMC provides support for MEF, but it is not a required dependency.  The project files do have a reference to System.ComponentModel.Composition (the MEF assembly) but unless you actually invoke the MEF Dependency Locator through policy, it will never be required at run-time.

And here is a MEF-based view-model with a test using the #Fellows AMC:

public class MefBlogViewModel
{
    private IAuthorRepository _authors;

    [ImportingConstructor]
    public MefBlogViewModel(IAuthorRepository authors)
    {
        _authors = authors;
    }

    [Import]
    public ISpamScoringService SpamScoring { get; set; }

    public void RecordComment(string author, string comment)
    {
        // Do something interesting here
    }
}

[TestClass]
public class MefBlogViewModelTests
{
    [TestMethod]
    public void TestMethod1()
    {
        // ARRANGE
        var container = new ObjectFactory();
        container.Policy.Set(new MefDependencyLocator());
        var viewModel = container.CreateObject<BlogViewModel>();
        var authorName = "author.name";
        var comment = "great stuff";

        // ACT
        viewModel.RecordComment(authorName, comment);

        // ASSERT
        container.GetDependency<IAuthorRepository>()
                 .AssertWasCalled(repo => repo.FindByName(authorName));
        container.GetDependency<ISpamScoringService>()
                 .AssertWasCalled(scoring => scoring.MeasureSpamScore(authorName, comment));
    }
}

The #Fellows AMC will inject against an [ImportingConstructor] (or will invoke a default parameter-less constructor) and will then inject against properties attributed with [Import].  Constructor parameters or properties attributed [ImportMany] are not currently supported for auto mock injection.

Now it takes quite a sharp eye to spot the difference in the test.  It is a single line of code that sets up MEF as part of the policy:

container.Policy.Set(new MefDependencyLocator());

What is Policy and how is it applied?

AutoMocking Policy is really what gives the #Fellows AMC its flexibility and is what sets it apart from the other AutoMocking Containers which are out there.  Put simply, policy consists of three areas:

AMC.Policy

Each of these areas be configured on an individual container (as per the above), or it can be configured at a static level where it will affect all containers in the AppDomain that are subsequently created.

ObjectFactory.DefaultPolicy.Set(new MefDependencyLocator());

Policy components that are currently available in #Fellows AMC are as follows:

Dependency Locators
  • Reflection-based (using the greediest constructor)     [default]
  • MEF-based
Lifecycle Controllers
  • Shared dependencies [default]
  • Non-shared dependencies
Mock Generators
  • Rhino Mocks

 

The three areas of policy work together to give the #Fellows AMC its overall behaviour.

Policy is an area that I think can be developed a lot further, both in terms of adding new policy components as well as allowing policy to be specified at a more granular level.  For instance:

  • specifying a mock generator that will instantiate object for classes in a given namespace
  • specifying that some classes should not have auto-mocking applied at all
  • specifying that certain dependencies should be shared whilst others should not

Furthermore, I suspect it would extremely useful to allow policy to be read from the config file.  This would allow us to centrally specify policy for all our tests without needing some code to adjust static state on the ObjectFactory.

Roadmap for the #Fellows AutoMockingContainer

The first thing I want to do is to get Silverlight support.  Or more specifically, an assembly which is compiled for Silverlight and against the relevant Silverlight assemblies (e.g. RhinoMocks SL version), since that is all that’s needed.  And after that, I’m hoping to extend the policy mechanism significantly.

Where can I get the #Fellows AutoMockingContainer?

Assemblies for .Net 4.0 are attached to this blog post.  If you are interested in the source code, then you can download it from the BitBucket repository.

SharpFellows.AutoMockingContainer.dll (13.00 kb)

Silverlight duplex communication, part 2: Reactive Extensions

 

In part 1 of this series I posted a Silverlight chat application that used duplex communications over HTTP.  Now to me, incoming data or events imply that the Reactive Framework (Rx) is probably a good fit for the application.  And so I decided to refactor the chatroom application to use Rx.

Introduction to Reactive Framework

Other (possibly  better) introductions can be found here, here or here, but I think that I a metaphor described by a colleague of mine is appropriate.  Usage of IEnumerable<T> can be likened to a water well – you pull the water out just as fast as you want it.  On the other hand, usage of IObservable<T> (a key Rx interface) can be likened to a spring of water – it just keeps pumping water at you and you better try and keep up!

On a slightly more detailed note, the main interfaces within Rx are IObservable<T> and IObserver<T>.  An Observable represents an event source while the Observer repesents an event sink.  Of course, an Observer can also be an Observable … think for a moment about an event filter that passes on some events while ignoring others.  Classes that implement IObservable<T> and IObserver<T> are known in Rx as “subjects”.

Interestingly, Rx chooses to represent an “event” as a method call.  So being an Observer (i.e. you receive events) actually just means that you receive method calls on your IObserver<T> interface.  And being an Observable (i.e. you raise events) actually just means that you make method calls to Observers who have registered an interest by subscribing.

Now you may be wondering what the generic type parameter T is used for.  Well that is the type of data that accompanies the event.  Bearing in mind that an event is just a method call, how do can you attach data to this?  Rx assumes that the data is actually the one and only parameter to the method.

This pattern is really at the heart of Rx.  It’s very easy to get lost in the plethora of extension methods and classes, but it’s crucial to always remember and try to apply that pattern.

Reactive Framework Extension Methods

And there are indeed a lot of very useful extension methods provided by the Rx framework.  Some of them perform filtering, some are useful in combining event streams (and so reducing concurrency) and others are useful in splitting event streams (and so increasing concurrency and parallelism). The best resource I’ve found has to be the Rx Wiki.  It describes all the operators and provides one or more example usages for most of them.

Using Rx in Silverlight

And now back to the subject in the title of this post!  :-)  There are a few assemblies which form the core of Rx for Silverlight:

  • System.Observable: contains the definitions for IObserver<T> and IObservable<T>
  • System.Reactive: contains all the extensions that support LINQ over Observers and Observables
  • System.CoreEx: concurrency constructs and other classes that support Rx

Note that on the desktop version of .Net 4.0, IObserver<T> and IObservable<T> are now included in mscorlib, which means that System.Observable is not used on that platform.  Sadly, this is not the case with Silverlight 4.0.

Creating an Observable

I’ll let the code speak for itself here:

public class ChatRoom
{
    // Other code omitted for clarity

    private readonly Subject<ChatData> _messages = new Subject<ChatData>();

    public IObservable<Timestamped<ChatData>> Messages
    {
        get { return _messages.Timestamp().AsObservable(); }
    }

    public void AddReceivedMessage(ChatData chatData)
    {
        _messages.OnNext(chatData);
    }
}

 

As you can see, we create a subject (_messages) and then expose it via the Messages property so that other code can consume the events.  When we are notified of a new message being received off the wire, we simply publish it on the subject.

Note that the code that actually listens to the network and calls the AddReceivedMessage method is included in the download and was explained in part 1 of this series.

We are making use of one interesting Rx feature here … the Timestamp extension method.  It takes an IObservable<T> and returns an IObservable<Timestamped<T>>, which in effect just adorns the object with the a new property holding the current date and time.

Consuming the Observable

Here is an embarrassingly trivial example:

ChatRoom.Instance.Messages.Subscribe(data => messages.Add(data));

This code is listening for events being raised from the subject and, when each one occurs, adding the new message to the “messages” collection which is bound onto the UI.  To be honest, this is not a particularly good illustration of what Rx is capable of, since the line of code here replaced an equally simple line of code that didn’t use Rx!

So let’s suppose that incoming message were extremely high volume, and instead of updating the UI as each message comes in, you decide you want to do it 4 times per second.  Without Rx this involves timers and so on.  With Rx, you replace the above line with the following:

ChatRoom.Instance.Messages
     .BufferWithTime(TimeSpan.FromMilliseconds(250))
     .Subscribe(buffer => buffer.ForEach(msg => messages.Add(msg)));

 

Or perhaps you want to implement some kind of command protocol using the message stream.  Something like this would work:

ChatRoom.Instance.Messages
    .Where(msg => msg.Data.StartsWith("pls.forward:"))                    
    .Subscribe(msg => ForwardMessage(msg));

 

Or (and IMO this is the most impressive aspect of Rx) if you want to do all of the above simultaneously, all you need to include the relevant lines.  You see, all the aspects of message processing here are totally separated and independent of each other.  And to me, that’s sweeeeeet!

Download the code: DuplexChatClient-with-Rx.zip (52.78 kb)
Newer Posts Older Posts