bling.github.io

This blog has relocated to bling.github.io.

Saturday, December 11, 2010

Auto Mocking NSubstitute with Castle Windsor

I was debating whether to make this blog post because it’s so damn simple to implement, but hey, if it saves someone else time, I did some good.

First of all, register an ILazyComponentLoader into Windsor:

var c = new WindsorContainer();
c.Register(Component.For<LazyComponentAutoMocker>());

Then, the implementation of LazyComponentAutoMocker is simply this:

public class LazyComponentAutoMocker : ILazyComponentLoader
{
  public IRegistration Load(string key, Type service, IDictionary arguments)
  {
    return Component.For(service).Instance(Substitute.For(new[] { service }, null));
  }
}

And you’re done!  Here’s a simple unit test example using only the code from above:

[Test]
public void IDictionary_Add_Invoked()
{
  var dict = c.Resolve<IDictionary>();
  dict.Add(1, 1);
  dict.Received().Add(1, 1);
}

That was almost too easy.

5 comments:

Randy said...

For what it's worth, I found this helpful. I'm new to Castle Windsor as well as NSubstitute. This post was able to get me going a lot quicker than sifting through documentation. Thanks.

Unknown said...
This comment has been removed by the author.
Unknown said...
This comment has been removed by the author.
Unknown said...

Just wanted to say that this approach didn't work for me - I'm guessing it might have something to do with a newer version of Castle Windsor? I fixed it by registering the component like this instead (where square brackets are in fact angle brackets - the comment system didn't like angle brackets):

_container.Register(Component.For[ILazyComponentLoader]().ImplementedBy[LazyComponentAutoMocker]());

Anonymous said...

I needed this for integration testing my Web API application. I found that I had to reject loading concrete classes, or NSubstitute would choke on the controller classes. So my implementation ended up looking like this:

if (!(service.IsInterface || service.IsAbstract))
{
// Do not register instances for concrete types
return null;
}

var mock = Substitute.For(new[] {service}, null);
return Component.For(service).Instance(mock);