Search code examples
c#unit-testingconfigurationmanager

Is there a way to set the configuration settings for a class that you are unit testing?


I've written all of the logic for my test project but I'm running into the problem of trying to set configuration variables in the class that I want to run. The class requires a workingDirectory variable to be set to a file path depending on what environment the program is being run in (for example production or test) and right now the variable is null. How do I get the configuration settings to run as if the class was being run normally (since the configuration settings are set when the class is run on its own or when it's not being tested)?

I've tried adding the app.config file that is used in the class being tested to the test project but that still won't set the configuration variables for me.

private static readonly string WorkingDir = ConfigurationManager.AppSettings["WorkingDirectory"];

var files = Directory.GetFiles($@"{WorkingDir}\in"); //this results in the 
//filepath being "C:\in" when testing since the WorkingDir configuration 
//variable doesn't get set when the class is called from the test project

<add key="WorkingDirectory" value="\\Test" xdt:Transform="Insert"/>

The configuration variable should be "\Test" when the class is run from the test project but instead is null or whitespace. This ends up being an error because there is not a directory that matches the string given to the Directory.GetFiles() line of code, and thus it won't find the files that I want it to find.


Solution

  • You need to create a service to provide configuration to your class:

    public interface IConfiguration 
    {
        string WorkingDirectory { get; }
    }
    
    public class ConfigurationManagerProvider: IConfiguration 
    {
        public WorkingDirectory => ConfigurationManager.AppSettings["WorkingDirectory"];
    }
    

    Then inject the IConfiguration service into your class, and have that class get its configuration from this service. You can now provide an alternative configuration by either mocking this interface or creating a second implementation.