0

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

Community
  • 1
  • 1
advapi
  • 3,661
  • 4
  • 38
  • 73
  • So what's your question? – stuartd Oct 12 '16 at 12:28
  • 1
    The very least you could do if you don't want to inject the configuration is make your application not use `ConfigurationManager.AppSettings` but a singleton of your choosing, that's more amenable to change. If you don't even want to do *that*, it is possible to [retarget the `.config` file being read at runtime](http://stackoverflow.com/questions/6150644/), hacky as this is (and decidedly sub-optimal for testing as you need to generate files). – Jeroen Mostert Oct 12 '16 at 12:29

1 Answers1

1

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.

toadflakz
  • 7,764
  • 1
  • 27
  • 40