ConfigurationManager.AppSettings在unit testing项目中返回Null

我在app.config文件中有一个带有应用程序设置的C#unit testing项目。 我正在测试一个存在于不同项目中的类。 该类依赖于ConfigurationManager.AppSettingsConfigurationManager.ConnectionStrings

被测试的类所在的项目没有app.config文件。 我原以为,因为该类正在unit testing项目的上下文中实例化,它将使用unit testing项目的app.config文件。 实际上,连接字符串似乎就是这种情况。

该类检索连接字符串没有任何问题。 但是,当类尝试检索任何应用程序设置时,配置管理器始终返回null 。 这里发生了什么?

编辑1

我想也许在测试项目中尝试加载一些设置以查看会发生什么是个好主意。 我试图在调用在外部项目中实例化类的代码之前立即加载unit testing中的设置。 同样的结果,没有。 我想我暂时可以从等式中排除其他项目。

这是我的配置文件的摘录:

   
... ...

以下是我尝试加载设置的方法:

 string test = System.Configuration.ConfigurationManager.AppSettings["Bing_Key"]; 

您在项目属性中提到了设置。 看看你是否可以这样访问设置:

 string test = Properties.Settings.Default.Bing_Key; 

您可能需要获取定义项目设置文件的执行程序集,但请先尝试此操作。

编辑

使用Visual Studio的项目设置文件时,它会向app.config添加内容并创建app.config(如果不存在)。 ConfigurationManager无法触摸这些设置! 您只能使用上面的静态方法获取这些特定生成的project.settings文件。 如果要使用ConfigurationManager,则需要手动编写app.config。 像这样添加你的设置:

    

考虑重构访问配置的代码以使用包装器。 然后,您可以为包装类编写模拟,而不必处理导入测试的配置文件。

在两者都很常见的库中,有这样的东西:

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

然后,在需要访问config的库中,将此接口类型的实例注入需要读取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 

然后,在其中一个库中,创建一个依赖于配置文件的实现。

 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()); } } 

然后,在调用您的类的代码中。

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

然后在你的测试中,你没有依赖束缚。 :)你可以创建一个实现IConfigurationWrapper的假版本并将其传递给你的测试,你可以从GetValueHasKey函数硬编码返回值,或者你正在使用像Moq这样的HasKey库:

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

这篇文章涵盖了这个概念(虽然对于Web表单,但概念是相同的): http : //www.schwammysays.net/how-to-unit-test-code-that-uses-appsettings-from织网,配置/

然后他尖叫着“NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO”。

Cite:我在app.config文件中有一个带有应用程序设置的C#unit testing项目。 我正在测试一个存在于不同项目中的类。 该类依赖于ConfigurationManager.AppSettings和ConfigurationManager.ConnectionStrings。

你不这样做。 EVER !!!! 为什么? 因为你现在已经创建了一个依赖项。 相反,使用dependency injection,以便类可以完成其工作,而不必进入属于应用程序的配置文件。