How to unit test a config file, (ConfigurationSection)

To unit test a ConfigurationSection in c# you need to do a couple of thing in your unit test
Of course, we do not want to change anything in the assembly being tested.

  • Create your own ConfigurationSection class
  • ‘Fake’ your own configuration file.
  • Test that you have the expected behaviour
    • For required values
    • Optional values

In your test application, create your own configuration loader class
It uses your configuration section as a template.

  internal class Loader where T : ConfigurationSection
  {
    // The filename that will contain the test contents.
    private string _fileName;
 
    // the instance we are testing
    public T Instance { get; }
 
    // the section we want to 'test' as well as the complete fake content
    public Loader(string section, string content)
    {
      File.WriteAllText(FileName, content);
      if (File.Exists(FileName))
      {
        var fileMap = new ExeConfigurationFileMap
        {
          ExeConfigFilename = FileName
        };
        var config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None, true);
        Instance = config.GetSection(section) as T;
      }
    }

Of course we also need to clean up things a little.
The file we created needs to be removed, you could also have this in your test teardown.

    ~Loader()
    {
      if (_fileName != null)
      {
        try
        {
          File.Delete(_fileName);
        }
        catch
        {
          // it will get deleted at some other point.
          // as it is a temp file the OS will/should remove ut
        }
        _fileName = null;
      }
    }

Creating the fake test file.

    private string FileName
    {
      get
      {
        if (_fileName != null)
        {
          return _fileName;
        }
        _fileName = Path.GetTempPath() + Guid.NewGuid() + ".config";
        return _fileName;
      }
    }
  }

Now testing the config is fairly straight forward, (using NUnit in this case)

(using the sample config content, my parser does not escape it properl)

<?xml version=""1.0"" encoding=""utf-8""?>
<configuration>
<configSections>
<section name=""blah"" type=""BlahConfiguration,MyApp.Blah"" />
</configSections>
<blah>
</blah>
</configuration>

    // in this example BlahConfiguration allows no values 
    public void SectionCanBeEmpty()
    {
      // sample configuration file.
      const string content =  // see content above;
 
      Loader<BlahConfiguration> cl = null;
      Assert.DoesNotThrow( () => cl = new ConfigLoader<BlahConfiguration>("blah", content));
      Assert.That( cl.Instance.Strings.Count == 0 );
    }

So now you can create your tests and just pass the values you want to test, default values for example, that values are loaded properly and so on.

Migrating from MSTest to NUnit

I am using VS2015 and VS2017 and I needed to migrate from Microsoft Unit tests to NUnit.

Those are the steps are followed.

  • In VS2015/2017 Select the “Package manager console” tab
    Select the correct project, (drop down combo), and type
 install-package nunit
  • Or using Nuget manager
    • Select the correct project.
    • Select NUnit, (just the plain ‘NUnit’ for now).
  • In your test project, look for “using Microsoft.VisualStudio.TestTools.UnitTesting;
    Replace with “using NUnit.Framework;“, (of course you will now have a whole bunch of errors.)
  • Look and replace
    • [TestClass] replace with [TestFixture]
    • [TestMethod] replace with [Test]
    • Remove code that looks like “[ExpectedException(typeof(xyz), “some text”)]” and surround the actual code that is expected to throw
Assert.Throws<xyz>(() => { BadCode(); });

NB: Note you might need to change a couple of other values

  • [TestInitialize] to [SetUp]
  • [TestCleanup] to [TearDown]
  • [TestClassInitialize] to [TestFixtureSetUp]
  • [TestClassCleanup] to [TestFixtureTearDown]

And a few other functions will need to change as well but for the most part they start with Assert.... and are fairly close(tm) to the Microsoft counterparts.