Singleton Unit Testing – A Different Approach

Peli has posted a tip concerning singleton objects and how them being singletons interferes with the testing itself. He also added a solution to this problem. Respect to Peli for this very cool post. :)

At first, I failed to understand his method, so I debated him a bit in his comments. Eventually, I understood what he meant – he created an instance manually each time he set-up his tests.

Here’s another way of doing this, if you have some instantiation code in your get accessor for Instance: Just nullify the static instance.

Here’s some code that shows how:

public class Singleton
{
    private static Singleton m_Instance;

    private Singleton()
    {
        // Do Initialization Magic
    }

    public static Singleton Instance
    {
        get
        {
            if (m_Instance == null)
            {
                m_Instance = new Singleton();

                // Do Instance Getting Magic
            }

            return m_Instance;
        }
    }
}

[TestFixture]
public class MyTests
{
    [TearDown]
    public void TearDown()
    {
        System.Reflection.FieldInfo fi =
            typeof(Singleton).GetField("m_Instance",
            System.Reflection.BindingFlags.Static |
            System.Reflection.BindingFlags.NonPublic);

        Assert.IsNotNull(fi);

        fi.SetValue(null, null);
    }
}

An added bonus for this method is the ability to use the Singleton class as it was intended for it to be used. There might be some code in the get accessor that should run whenever it is accessed, regardless for the value of the private instance.

Advertisements

2 thoughts on “Singleton Unit Testing – A Different Approach

  1. Nice tip, but the destructor of the singleton isn’t called at the end of the test (but only when you exit nunit). I tried to find a way to force it to be called (including GC.Collect/WaitForPendingFinalizers) but didn’t manage to :-(
    Do you have a clue
    Thank you

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s