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?
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.