C# 执行单元测试时,ConfigurationManager.GetSection(sectionName)返回null

C# 执行单元测试时,ConfigurationManager.GetSection(sectionName)返回null,c#,.net,configuration,nunit,configurationmanager,C#,.net,Configuration,Nunit,Configurationmanager,我有一个单元测试项目,它有自己的app.config文件,这是一个模拟被测试的目标项目定义的真实配置文件。这个模拟文件是由单元测试代码(而不是目标项目)加载和处理的,如果我只在这个测试项目中运行测试,它会正常工作 ConfigurationManager.GetSection(sectionName) 但是,如果我从几个测试项目中运行测试,并且其他测试项目在相关项目之前执行,则上述语句返回null。若讨论的测试项目作为第一个执行,那个么加载配置文件并没有问题 如何修复单元测试中配置文件的加载以

我有一个单元测试项目,它有自己的
app.config
文件,这是一个模拟被测试的目标项目定义的真实配置文件。这个模拟文件是由单元测试代码(而不是目标项目)加载和处理的,如果我只在这个测试项目中运行测试,它会正常工作

ConfigurationManager.GetSection(sectionName)
但是,如果我从几个测试项目中运行测试,并且其他测试项目在相关项目之前执行,则上述语句返回
null
。若讨论的测试项目作为第一个执行,那个么加载配置文件并没有问题


如何修复单元测试中配置文件的加载以正常工作?

您的问题不是ConfigurationManager。GetSection(sectionName)返回null,而是如何测试包含ConfigurationManager.GetSection(sectionName)的某些代码

答案是:包装它,注入它,然后在测试中模拟它

您有几个人面临相同问题的例子:

(第二个要详细得多,但想法是一样的)


无论如何,这是非常合乎逻辑的,您不能在单元测试中使用app.config中的信息,因为app.config是整个应用程序的上下文,而需要绝对独立地编写测试。如果直接使用app.config值,则存在非逻辑耦合。

面对同样的问题,这解决了它: 如果
app.config
属性设置为
Copy if newer
,或者如果您添加了DeploymentItem属性
[DeploymentItem(“您的.config”)]
,则应在单元测试中拾取
app.config

更详细的说明:


类似的问题:

我认为问题可能是在测试工作目录中找不到文件,或者文件本身无法加载

我通过显式加载名为的配置文件解决了这个问题。在你的情况下,你也可以试试

ExeConfigurationFileMap configMap = new ExeConfigurationFileMap();
configMap.ExeConfigFilename = @"d:\test\test.config";
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.None);

我使用了测试项目生成后命令行,但是如果有更改,请记住生成项目:

copy /Y "$(SolutionDir)$(SolutionName)\App.Debug.config" "$(TargetDir)$(ProjectName)$(TargetExt).config"

每次运行测试项目时,我都会遇到与测试项目和Sqlite类似的问题,因为创建了一个新的Sqlite数据库,而主项目没有这样做,所以为了进行测试,我必须创建普通的控制台应用程序,而不是测试项目。我不知道这些信息是否有用一些案例测试项目不是很好,尤其是当涉及到处理外部资源时,是什么让我在Visual2010中面临这个问题更奇怪,但当我升级到2012年时,一切都正常!!!我认为您只能有一个活动配置文件,第一个文件是用于所有项目的文件,当您有正常项目时,这已完成,但在测试项目中未完成,因此请将web配置复制(合并)到所有项目,并查看其是否工作。因此,您在一个单元测试项目中有一个app.config,而其他单元测试项目依赖于该app.config?这是不可持续的。我建议要么将mock app.config复制到每个测试项目中,要么使用下面@Ouarzy的mock建议。它还取决于您正在测试的内容:ConfigurationManager.GetSection()调用或其他一些东西。这一切都很好,但是如果您试图测试的是与configuration manager相关的代码呢?我正处于这种情况,我发现的所有建议都说我应该从测试中提取ConfigurationManager,但如果我这样做,那么就没有什么可测试的了。如果在提取ConfigurationManager时没有什么可测试的,这对我来说意味着你需要一个重构来实现更好的责任分离。你能得到比一个类更多的分离,这个类的唯一目的是使用ConfigurationManager获取或更改值,实现一个获取和设置配置值的接口?我想这个讨论可能会很长,没有示例:)如果您希望通过ouarzy'at'free.fr与我联系,并通过GitHub共享一些代码,我们可以讨论它