How to mock config file for unit test

Vicky picture Vicky · Aug 28, 2017 · Viewed 11.1k times · Source

I have a class in which there is a parameter less constructor. But when this constructor is called, there are five properties of the class that gets values from config file in the constructor. There are two method in the class which uses the parameters that get initialized in the constructor.

I want to write unit test for two methods using mock framework. But, I am not sure of how to initialize the parameters in the constructor as calling the method will not provide the value to those properties.

public class ABC
{
   public ABC()
   {
      a = ConfigurationManager.AppSetting["GetValue"];
      b = ConfigurationManager.AppSetting["GetValue1"];
   }

   public int Method1(IDictionary<string, string> dict)
   {
      d = a + b /2; (how to mock values of a and b while writing unit tests 
                     using mock framework. In reality, a in my case is 
                     dictionary)

//some business logic

      return d;
   }
}

Thanking in advance,

Answer

Vijayanath Viswanathan picture Vijayanath Viswanathan · Aug 30, 2017

You cannot Mock values of a and b as your code is tightly coupled with app.config file. You can create an interface. Refactor code like below to inject an interface to you constructor and then mock it,

 public class ABC
    {
        private int a;
        private int b;
        public ABC(IConfig config)
        {
            a = config.a;
            b = config.b;
        }

        public int Method1(IDictionary<string, string> dict)
        {
            int d = a + b / 2;

            return d;
        }
    }

    public interface IConfig
    {
        int a { get; }
        int b { get; }
    }
    public class Config : IConfig
    {
        public int a => Convert.ToInt32(ConfigurationManager.AppSettings["GetValue"]);
        public int b => Convert.ToInt32(ConfigurationManager.AppSettings["GetValue1"]);
    }

And in you test class Mock and inject IConfig like below,

Mock<IConfig> _mockConfig = new Mock<IConfig>();

        _mockConfig.Setup(m => m.a).Returns(1);
        _mockConfig.Setup(m => m.b).Returns(2);

        ABC abc = new ABC(_mockConfig.Object);

Now your code is decoupled with app.config and you will get mock values of a and b while running unit test.