Click here to Skip to main content
Click here to Skip to main content

Unit testing Singleton

By , 22 Feb 2013
 

Introduction

One of the simplest patterns to learn and implement and one of the most controversial patterns is the Singleton pattern. If there is a need to control the access of a shared resource, Singleton pattern perfectly fits into the picture.

The problem arises when unit testing needs to be performed on it. Singleton leads to external dependencies, which is hard for unit testing.

For example: when we write a unit test, we fake our object such that it returns only the desired result.
In case of singleton, while faking we set the instance of singleton with our desired result, all other code instantiating singleton will have the same object. To overcome this, we can call a singleton from an interface.

Using Singleton from an Interface

First of all, extract an interface from the Singleton class and then apply Dependency Injection. We need interface for decoupling purpose and unit testing.

public interface ISingletonClass
{
    string conn;
}

Singleton class implementing the interface:

namespace Singleton2DI
{
    public class SingletonClass : ISingletonClass
    {
        private static readonly string conn;

        static SingletonClass()
        {
            try
            {
                conn = "This is original class value";
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public string Conn()
        {
                return conn;
        }
    }
}

Accessing singleton class from another class, the instance would then be passed to any objects that might trying to implement it through the property.

With DI, its just a matter of configuration, we can have single or multiple instances

public class SClass
{
    private ISingletonClass _sc;
    public ISingletonClass SC
    {
        get
        {
            if (_sc == null)
                _sc = new SingletonClass();
            return _sc;
        }
        set
        {
            _sc = value;
        }
    }

    public virtual string ReturnConn()
    {
        return SC.Conn();
    }
}

Points of Interest

Unit testing using MOQ framework, we can easily pass a fake object for unit tests, without bothering for an extra instance to haunt...

[TestMethod()]
public void ReturnConnTest()
{
    SClass target = new SClass(); 
    string expected = "This is MOQ class"; 
    string actual;
    Mock<SClass> moqClass = new Mock<SClass>();
    moqClass.Setup(mc => mc.ReturnConn()).Returns(expected);
    target = moqClass.Object;
    actual = target.ReturnConn();
    Assert.AreEqual(expected, actual);
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

AmitMukherjee
Technical Lead Aditi
India India
Member
A simple guy who loves the software development and enjoys being involved in the software development / creation process and looking forward to know more and more in this magnificent field.

I have worked in various areas in software process and gained a solid experience during my 7 years professional tenure in software designing, development and management.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionLet the container do the workmemberstooboo22 Feb '13 - 7:46 
Wouldn't it be better to write your SingletonClass as an ordinary class (i.e. no static vars) implementing your ISingletonClass
.. and then let the DI container handle the 'singleton' or 'transient' .. or whatever life time behaviour you wanted
 
e.g. in Microsoft Unity register it with a ContainerControlledLifetimeManager then it WILL be a singleton
 
then ... if you changed your mind (or requirements change) you could change the 'lifetime manager' and make it (for instance) per-web-request .. without changing a single line of the code in the SingletonClass
 
This then really would release you from ALL the pitfalls of the Singleton Pattern
 
Also .. if you're using IOC/DI your line ' _sc = new SingletonClass();' is a code smell you don't want !
 
stu
AnswerRe: Let the container do the workmemberAmitMukherjee22 Feb '13 - 15:26 
[Wouldn't it be better to write your SingletonClass as an ordinary class (i.e. no static vars) implementing your ISingletonClass
.. and then let the DI container handle the 'singleton' or 'transient' .. or whatever life time behaviour you wanted ]
-There are various ways to implement singleton, all will server the same purpose, even what you stated the ordinary class would also serve the same.
 
[Also .. if you're using IOC/DI your line ' _sc = new SingletonClass();' is a code smell you don't want !]
You are correct the code has an abstraction layer between the different class interaction, but not used DI as such. The code can be modified as:

private ISingletonClass singletonobj;
public SClass(ISingletonClass singleton)
{
this.singletonobj = singleton;
}

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 22 Feb 2013
Article Copyright 2013 by AmitMukherjee
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid