7

I have created a custom ConfigurationElement and ConfigurationSection to make it easier to set up a host of application parameters at startup. However, I'd really like to unit test this logic.

ServiceConnection

public class ServiceConnection : ConfigurationElement
{
    [ConfigurationProperty("locationNumber", IsRequired = true)] 
    public string LocationNumber
    {
        get { return (string) base["locationNumber"]; }
        set { base["locationNumber"] = value; }
    }

    [ConfigurationProperty("hostName", IsRequired = true)]
    public string HostName
    {
        get { return (string) base["hostName"]; }
        set { base["hostName"] = value; }
    }

    [ConfigurationProperty("port", IsRequired = true)]
    public int Port
    {
        get { return (int) base["port"]; }
        set { base["port"] = value; }
    }

    [ConfigurationProperty("environment", IsRequired = true)]
    public string Environment
    {
        get { return (string) base["environment"]; }
        set { base["environment"] = value.ToUpper(); }
    }

    internal string Key
    {
        get { return string.Format("{0}|{1}", LocationNumber, Environment); }
    }
}

ServiceConnection Collection

[ConfigurationCollection(typeof(ServiceConnection), AddItemName = "service", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class ServiceConnectionCollection : ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        return new ServiceConnection();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((ServiceConnection) element).Key;
    }

    public ServiceConnection Get(string locationNumber, string environment = "PRODUCTION")
    {
        return (ServiceConnection) BaseGet(string.Format("{0}|{1}", locationNumber, environment));
    }

    public ServiceConnection this[int index]
    {
        get { return (ServiceConnection)BaseGet(index); }
        set
        {
            if (BaseGet(index) != null)
            {
                BaseRemoveAt(index);
            }
            BaseAdd(index, value);
        }
    }
}

Some Test XML

<MyServiceConnections>
    <service locationNumber="0AB0" hostName="DEVSERVER" port="1234" environment="DEVELOPMENT" />
    <service locationNumber="0AB0" hostName="BETASERVER" port="1234" environment="BETA" />
    <service locationNumber="0AB0" hostName="PRODSERVER" port="1234" environment="PRODUCTION" />
</MyServiceConnections>

In my production code, I'm using ConfigurationManager to retrieve the ServiceConnection but am not sure how to create a test that bypasses the manager altogether.

I'm looking to retrieve a ServiceConnection object and make sure all the fields match the input that I set up in the test XML. I'd also like to test functionality when a user failed to populate one or more of the fields.

4
  • Can you explain what exactly you want to test? I would extract the ConfigurationManager code from the actual implementation and inject that. Commented Aug 14, 2014 at 13:08
  • @CodeCaster: Edited. "I'm looking to retrieve a ServiceConnection object and make sure all the fields match the input that I set up in the test XML. I'd also like to test functionality when a user failed to populate one or more of the fields." I've used this code in another project some time ago and ran into issues on the build server (TeamCity) when running against the live App.config and trying to use ConfigurationManager. I'd like to bypass it entirely, if possible. Not sure if an XmlReader is the right track. Commented Aug 14, 2014 at 13:18
  • 1
    stackoverflow.com/questions/15133379/…? Commented Aug 14, 2014 at 13:29
  • A way to test without ConfigurationManager.GetSection (and configuration by file) using an adapted section constructor taking string as argument: stackoverflow.com/a/704817/954701 Commented Feb 26, 2018 at 9:05

1 Answer 1

11

Well, I ended up simply going with what @CodeCaster suggested and using ConfigurationManager anyway (as suggested by his link here).

I've posted a sample test below:

[Test]
public void ShouldProvideFullProductionServiceConnectionRecord()
{
    //NOTE: Open ConfigTests.config in this project to see available ServiceConnection records

    //Arrange
    ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap { ExeConfigFilename = "ConfigTests.config" };
    Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

    ServiceConnectionSection section = config.GetSection("AutomationPressDataCollectionServiceConnections") as ServiceConnectionSection;

    //Act
    var productionSection = section.Connections.Get("0Q8");

    //Assert
    Assert.AreEqual("0AB0", productionSection.LocationNumber);
    Assert.AreEqual("DEVSERVER", productionSection.HostName);
    Assert.AreEqual(1234, productionSection.Port);
    Assert.AreEqual("DEVELOPMENT", productionSection.Environment);
}

It requires you add a new .Config file and set its output as Content and set to Copy if Newer (it's in a unit test project). But it's better than having no coverage at all.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.