views:

414

answers:

2

I'm using component from a third party. The component provide a singleton pattern for context into our application. I'm using on my side this singleton but I would like to mock this object for my test. Is there any way to accomplish a mock on this object.

Also, the constructor is declared private.

A: 

If the third party Singleton returns an interface rather than a concrete class (it should), then Rhino mocks will be able to mock it.

If you just want to stub it out, check out Rhino mocks' MockRepository.Stub<IMyInterface>()

Mitch Wheat
+2  A: 

With RhinoMocks you have to have an interface. If you really need to mock this, then you will have to cheat a bit by wrapping the singleton in another class that instantiates an interface. This interface needs to basically be a carbon copy of all public members on the third party singleton type.

The concept is similar to Duck Typing, but since the CLR doesn't support Duck Typing you have to use the proxy class.

Here is an example:

public interface ISingleton
{
    void SomePublicMethod();
    Int32 SomePublicProperty{ get; set; }
}

public class SingletonProxy: ISingleton
{
    private ThirdPartySingleton _singleton = StaticType.GetSingleton(); // ???

    public void SomePublicMethod()
    {
        _singleton.SomePublicMethod();
    }

    public Int32 SomePublicProperty
    {
        get{ return _singleton.SomePublicProperty; }
        set{ _singleton.SomePublicProperty = value; }
    }
}

So now in whatever type you are using this in, you can pass this in as a service dependency like so:

public class TypeThatUsesSingleton
{
    private ISingleton _singleton;    

    public TypeThatUsesSingleton([HopefullySomeDependencyInjectionAttributeHere] ISingleton singleton)
    {
        _singleton = singleton;
    }

    public void DoStuff()
    {
        _singleton.SomePublicMethod();
    }
}

Now you should be able to happily mock the class in your test and pass it in as the dependency in order to get your unit tests rolling along:

[Test]
public void ShouldAssertSomeBehavior()
{
    var repo = new MockRepository();
    var singleton = repo.DynamicMock<ISingleton>();

    var sut = new TypeThatUsesSingleton(singleton);

    using(repo.Record())
    {
        singleton.SomePublicMethod();
    }
    using(repo.Playback())
    {
        sut.DoStuff();
    }
}

Voila! Happily mocked singleton without the headache (ok, so a little headache). You are probably thinking that the whole Proxy class is going to be a pain in the butt, but luckily some good folks have made this a little easier. The whole Duck Typing thing I mentioned earlier... there is an open source library that will generate your proxy class for you at runtime.

Duck Typing .Net

Josh