ConfigurationManager.AppSettings Returns Null In Unit Test Project

前端 未结 4 443
故里飘歌
故里飘歌 2021-02-05 05:47

I have a C# unit test project with application settings in the app.config file. I am testing a class that exists in a different project. That class depends on bot

4条回答
  •  名媛妹妹
    2021-02-05 06:07

    Consider refactoring your code that accesses the config to use a wrapper. Then you can write mocks for the wrapper class and not have to deal with the importing of the configuration file for the test.

    In a library that is common to both, have something like this:

    public interface IConfigurationWrapper {
    
        string GetValue(string key);
        bool HasKey(string key);
    }
    

    Then, in your libraries that need to access config, inject an instance of this interface type into the class that needs to read config.

    public class MyClassOne {
        
        private IConfigurationWrapper _configWrapper;
    
        public MyClassOne(IConfigurationWrapper wrapper) {
            _configWrapper = wrapper;
        } // end constructor
    
        public void MethodThatDependsOnConfiguration() {
            string configValue = "";
            if(_configWrapper.HasKey("MySetting")) {
                configValue = _configWrapper.GetValue("MySetting");
            }
        } // end method
    
    } // end class MyClassOne
    

    Then, in one of your libraries, create an implementation that depends on the config file.

    public class AppConfigWrapper : IConfigurationWrapper {
        
        public string GetValue(string key) {
            return ConfigurationManager.AppSettings[key];
        }
    
        public bool HasKey(string key) {
           return ConfigurationManager.AppSettings.AllKeys.Select((string x) => x.ToUpperInvariant()).Contains(key.ToUpperInvariant());
        }
    }
    

    Then, in the code that calls your class.

    //Some method container
    MyClassOne dataClass = new MyClassOne(new AppConfigWrapper());
    
    dataClass.MethodThatDependsOnConfiguration();
    

    Then in your test, you are free from dependency bondage. :) You can either create a fake version that implements IConfigurationWrapper and pass it in for your test, where you hard-code the return values from the GetValue and HasKey functions, or if you're using a mocking library like Moq:

    Mock fakeWrapper = new Mock();
    
    fakeWrapper.Setup((x) => x.GetValue(It.IsAny)).Returns("We just bypassed config.");
    
    MyClassOne testObject = new MyClassOne(fakeWrapper.Object);
    testObject.MethodThatDependsOnConfiguration();
    

    Here is an article that covers the concept (albeit, for web forms, but the concepts are the same): http://www.schwammysays.net/how-to-unit-test-code-that-uses-appsettings-from-web-config/

提交回复
热议问题