Search code examples
c#unit-testingintegration-testingsystem-testing

How to test a web service with different configurations?


I want to automatically test http://localhost/api.ashx.

api.ashx reads configurations from web.config and acts differently.

For example one key is AllowDuplicatedQueryParameter. If web.config has

<appSettings>
  <add key="AllowDuplicatedQueryParameter" value="false" />
</appSettings>

requesting to http://localhost/api.ashx?name=hello&name=world will throw error.

How do I have an automated test that tests different configurations, namely when AllowDuplicatedQueryParameter=true and AllowDuplicatedQueryParameter=false?


Solution

  • It depends a bit on what kind of automated testing you want to do. Under the circumstances, unit testing or integration testing against a in-process version of your application seems like it would make sense.

    Your best option in these cases is to abstract the reading of the configuration into a class that can be mocked. For example, imagine the configuration you change is in your AppSettings you might do something similar to this

    public interface IConfigurationWrapper
    {
        string GetAppSetting(string key);
    }
    
    public class ConfigurationWrapper : IConfigurationWrapper
    {
         public string GetAppSetting(string key)
         {
             return ConfigurationManager.AppSettings[key]
         }
    }
    

    Your components should take a dependency on an
    IConfigurationWrapper, and use it whenever you need to access configuration to determine behavior. In your test, you can use a mocking library like Moq or NSubstitute, or roll your own stub implementation of the IConfigurationWrapper and use that to controll the behavior of the system under test, like this:

    public class MyThingDoer
    {
        public MyThingDoer(IConfigurationWrapper config)
        {
             _config = config
        }
    
        public string SaySomething()
        {
            var thingToSay = _config.GetAppSetting("ThingToSay");
            return thingToSay;
        }
    }
    

    And then in your test

    [Fact]
    public void ThingDoerSaysWhatConfigTellsItToSay()
    {
        var configWrapper = new FakeConfigWrapper(thingToSay:"Hello");
        var doer = new MyThingDoer(configWrapper);
        Assert.Equal("Hello", doer.SaySomething());
    }
    

    Obviously that's a toy example, but it should get at the basic idea. Write an abstraction around the external dependency, then stub the dependency.