When unit testing a class that relies on app settings you don't want to be setting up web.config to get it running. I realised today that app settings are a dependency of a class. Therefore they must be injected by the IoC container. I'm using Ninject...
I have this in my web.config:<appSettings> <add key="bar" value="1234" /> </appSettings>
I want to inject that value into a class constructor as below:
class Foo { public Foo(AppSetting bar) { ... }}
AppSetting is a simple wrapper around a string:class AppSetting { public AppSetting(string value) { Value = value; } public string Value { get; private set; }}
I then configure Ninject with:Bind<AppSetting>().ToProvider<AppSettingProvider>();
Where AppSettingProvider is:class AppSettingProvider : Ninject.Core.Creation.IProvider{ public object Create(Ninject.Core.Activation.IContext context) { return new AppSetting(WebConfigurationManager.AppSettings[context.Target.Name]); }
public Type GetImplementationType(Ninject.Core.Activation.IContext context) { return typeof(AppSetting); }
public bool IsCompatibleWith(Ninject.Core.Activation.IContext context) { return WebConfigurationManager.AppSettings[context.Target.Name] != null; }
public Type Prototype { get { return typeof(AppSetting); } }}
The end result is a class that can be trivially unit tested, since it never calls the configuration API directly. Also, there was no need to create some complex abstraction around the API just to enable unit testing. In the future I can even change how and where app settings are stored (maybe using a database for example) all I'd have to do is make a new provider.
Ninject - in a word: awesome!
Powered by: newtelligence dasBlog 2.2.8279.16125
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2010, Andrew Davey
E-mail