单元测试项目可以加载目标应用程序的 app.config 文件吗?

我正在单元测试一个。NET 应用程式(。Exe) ,它使用 app.config 文件加载配置属性。单元测试应用程序本身没有 app.config 文件。

当我尝试单元测试一个使用任何配置属性的方法时,它们返回 无效。我假设这是因为单元测试应用程序不会加载到目标应用程序的 app.config 中。

有没有办法覆盖它,或者我必须编写一个脚本来将目标 app.config 的内容复制到本地 app.config?

这篇文章有点像是在问这个问题,但作者确实是从一个与我不同的角度来看待这个问题的。

编辑: 我应该提到,我正在使用 VS08 Team System 进行单元测试。

157144 次浏览

最简单的方法是在单元测试的部署部分中添加 .config文件。

为此,请从解决方案项中打开 .testrunconfig文件。在 Deployment 部分,从项目的构建目录(大概是 bin\Debug)添加输出 .config文件。

在运行测试之前,部署部分中列出的任何内容都将被复制到测试项目的工作文件夹中,因此依赖于配置的代码将正常运行。

编辑: 我忘了添加,这不会在所有情况下工作,所以您可能需要包括一个启动脚本,重命名输出 .config,以匹配单元测试的名称。

如果您正在使用 NUnit,请看一下 这篇文章。基本上,您需要将 app.config 放在与您的。单元文件。

我使用 NUnit,并且在我的项目目录中有我的应用程序的一个副本。配置我改变了一些配置(例如我重定向到一个测试数据库...)。您需要在测试项目的 同一个目录中使用它,这样就可以了。

无论您使用的是 团队系统测试还是 NUnit,最佳实践是为您的测试创建一个单独的类库。只需将 App.config 添加到您的 Test 项目中,就会在编译时自动复制到 bin 文件夹中.

如果您的代码依赖于特定的配置测试,那么我编写的第一个测试将验证配置文件是否可用(这样我才知道我没疯) :

<configuration>
<appSettings>
<add key="TestValue" value="true" />
</appSettings>
</configuration>

还有测试:

[TestFixture]
public class GeneralFixture
{
[Test]
public void VerifyAppDomainHasConfigurationSettings()
{
string value = ConfigurationManager.AppSettings["TestValue"];
Assert.IsFalse(String.IsNullOrEmpty(value), "No App.Config found.");
}
}

理想情况下,您应该编写代码,以便将配置对象传递到类中。这不仅将您与配置文件问题分开,而且还允许您为不同的配置方案编写测试。

public class MyObject
{
public void Configure(MyConfigurationObject config)
{
_enabled = config.Enabled;
}


public string Foo()
{
if (_enabled)
{
return "foo!";
}
return String.Empty;
}


private bool _enabled;
}


[TestFixture]
public class MyObjectTestFixture
{
[Test]
public void CanInitializeWithProperConfig()
{
MyConfigurationObject config = new MyConfigurationObject();
config.Enabled = true;


MyObject myObj = new MyObject();
myObj.Configure(config);


Assert.AreEqual("foo!", myObj.Foo());
}
}

在 VisualStudio2008中,我将 app.config文件作为一个现有项目添加到测试项目中,并选择了副本作为链接,以确保它不会被复制。这样我的解决方案中只有一个副本。随着几个测试项目,它真的很方便!

Add Existing Item

Add As Link

我无法得到这些建议中的任何一条来使用 nUnit 2.5.10,所以我最终使用 nUnit 的 Project-> Edit 功能来指定目标配置文件(正如其他人所说,它需要与。Nunit 文件本身)。这样做的好处是,我可以给配置文件一个 Test.config 名称,这样就可以更清楚地看到它是什么以及为什么是它)

如果您有一个包含例如 Web Application 和 Test Project 的解决方案,那么您可能希望 Test Project 使用 Web Application 的 Web.config。

解决方法之一是将 web.config 复制到测试项目,并将其重命名为 app.config。

另一个更好的解决方案是修改构建链并使其自动复制 web.config 以测试项目输出目录。为此,右键单击 TestApplication 并选择属性。现在您应该看到项目属性。单击“ Build Events”,然后单击“ Edit Post-Build...”按钮。在这里写下一行:

copy "$(SolutionDir)\WebApplication1\web.config" "$(ProjectDir)$(OutDir)$(TargetFileName).config"

然后点击确定。(注意,您最可能需要将 WebApplication1更改为您想要测试的项目名称)。如果你有错误的路径到 web.config 然后复制失败,你会注意到它在不成功的构建。

编辑:

从当前项目复制到测试项目:

copy "$(ProjectDir)bin\WebProject.dll.config" "$(SolutionDir)WebProject.Tests\bin\Debug\App.Config"

如果您的应用程序正在使用 Asp.net ConnectionString 之类的设置,那么您需要将属性 HostType 添加到您的方法中,否则即使您有一个应用程序,它们也不会加载。配置文件。

[TestMethod]
[HostType("ASP.NET")] // will load the ConnectionString from the App.Config file
public void Test() {


}

这很简单。

  • 右键单击您的测试项目
  • 添加-> 现有项目
  • 您可以看到 Add 按钮旁边有一个小箭头
  • 点击“添加为链接”选择配置文件

这是一个有点老,但我找到了一个更好的解决方案。我正在尝试选择的答案在这里,但看起来像。Testrunconfig 已经过时。

1. 对于单元测试,包装配置是一个接口(IConfig)

对于单元测试,配置实际上不应该是测试的一部分,所以创建一个可以注入的 mock。在这个例子中,我使用的是 Moq。

Mock<IConfig> _configMock;
_configMock.Setup(config => config.ConfigKey).Returns("ConfigValue");
var SUT = new SUT(_configMock.Object);

对于集成测试,动态添加所需的配置

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if(config.AppSettings.Settings[configName] != null)
{
config.AppSettings.Settings.Remove(configName);
}
config.AppSettings.Settings.Add(configName, configValue);
config.Save(ConfigurationSaveMode.Modified, true);
ConfigurationManager.RefreshSection("appSettings");

单元测试被视为运行代码进行测试的环境。就像任何正常的环境一样,您有即准备/生产。您可能还需要为您的测试项目添加一个 .config文件。解决方案是创建一个类库,并通过添加必要的 NuGet 包(如 NUnit 和 NUnit Adapter)将其转换为 Test Project。它与 VisualStudioTestRunner 和 Resharper 都可以很好地工作,并且在测试项目中有 app.config文件。 enter image description here

enter image description here

enter image description here

enter image description here

最后从 App.config调试了我的测试和值:

enter image description here