advapi
advapi

Reputation: 3907

Mocking up ConfigurationManager.Appsettings without using Facade Approach

I was to test a method and I got everything working except for the fact I'm not able to moq the ConfigurationManager.AppSettings.

My method is defined as

  public async Task<IDictionary<string, object>> Action(IDictionary<string, object> context)
    {
        if (ConfigurationManager.AppSettings[ApplicationUserFromDomainUserKey] == null)
            throw new ConfigurationErrorsException(ApplicationUserFromDomainUserKey);
        string storedProcedure = ConfigurationManager.AppSettings.Get(ApplicationUserFromDomainUserKey);

        if (ConfigurationManager.ConnectionStrings[DbConnectionKey] == null)
            throw new ConfigurationErrorsException(DbConnectionKey);
        ...

}

I've seen in this question that an approach using the facade approach would be nice but it would dirt my class implementation which doesn't make use of IoC / DI

I've read as well this intresting article but this only applies to Vs Enterprise edition and I wish it to be runnable on CI/ VS professional edition

I'm using NUnit for testing and my test is

        [Test]
    public void MissingAppSettingsKey()
    {
            var pipeline = new RetrieveApplicationUsernamePipelineStep();

            var context = new Dictionary<string, object>()
            {
                [Resources.DomainUser] = "andrea",
                [Resources.Domain] = "ifinformatica.net",
                [Resources.ApplicationId] = 0
            };

            Assert.ThrowsAsync<ConfigurationErrorsException>(async () => await pipeline.Action(context));

        }

    }

P.S. I also use resharper's tools for testing which excludes me to run the microsoft unit test framework as well

Upvotes: 0

Views: 2674

Answers (1)

toadflakz
toadflakz

Reputation: 7934

The simpler approach would be to start using a limited implementation of DI to remove the ConfigurationManager dependency.

Overload your constructor (whatever it was) to take the AppSettings entries as parameters.

So if you created your object like so:

  MyObject myObj = new MyObject(SomeParam);

..with constructor declaration of...

  public MyObject(ParamObj someParam)
  {
    //...implementation....
  }

...overload it like so...

  public MyObject(ParamObj someParam)
   : this(someParam, Convert.ToInt32(ConfigurationManager.AppSettings["mySetting"]))
  {
    //...implementation....
  }


  public MyObject(ParamObj someParam, int mySettingValue)
  {
    //...implementation....
  }

This means when you test, you construct objects using the constructor which does not call/require ConfigurationManager.

Upvotes: 1

Related Questions