In unit-tests you sometimes find yourself in a situation that you need to mock a configuration section. The ConfigurationSection
class (or your inherited class) encapsulates nicely and there is no easy way how to break it’s read-only public interface.
You might consider abstracting the whole section and/or exposing it via some kind of adapter, but sometimes you don’t need to be 100% pure and still want get some basic test coverage.
There is an obscure but functional way how to mock the ConfigurationSection (or a whole configuration file if needed):
1. Create a fake configuration file in your test project
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="mySection" type="MyConfigurationSection, MyAssembly" /> </configSections> <mySection> <identities> <identity clientId="fake_id" name="FAKE_NAME" partitionName="FAKE_PARTITION" permissions="Full" /> </identities> </mySection> </configuration>
The file can be placed in any directory in test project. Right beside your test-class might be the right place.
2. Set the configuration file to be copied to build output
In Properties of the configuration file, set:
- Build Action = Content
- Copy to Output Directory = Copy always
3. Create a unit-test which uses the file to build a fake configuration
[TestClass] public class MyServiceTests { public TestContext TestContext { get; set; } [TestMethod] [DeploymentItem("PathInTestProject\\MyServiceTests_ScenarioName.config")] public void MyService_DoSomething_ScenarioName_ExpectedBehavior() { // arrange ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap() { ExeConfigFilename = Path.Combine(TestContext.DeploymentDirectory, "MyServiceTests_ScenarioName.config") }; Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None); MyConfiguarionSection mySection = config.GetSection("mySection") as MyConfiguarionSection ; var sut = new MyService(mySection); // act ... } }
The basics:
- The
ConfigurationManager.OpenMappedExeConfiguration()
method allows you to use any configuration file you want. - The
[DeploymentItem(...)]
attribute copies the config file from build output to the “test deployment directory” (e.g. $(SolutionDir)\TestResults\Deploy_username 2017-09-29 22_02_39\Out\) - The
TestContext.DeploymentDirectory
contains the path whereas theTestContext
property is automatically injected with appropriate instance of the test context.