对ASP .NET应用程序进行单元测试时如何使用web.config


74

我从单元测试开始,我有一个使用web.config作为连接字符串的方法。

我希望能够使用

[DeploymentItem("web.config")]

要获取Web配置文件,这仍然给我留下了null引用异常(这就是我编写下一个测试的目的)。

如何使用我要测试的项目随附的配置文件?

我正在使用VS 2008中包含的测试框架,如果有什么不同的话。

谢谢


您是否将单元测试代码与应用程序代码放在同一项目中?
Gerrie Schenck,2009年

+1,我今天有同样的问题。可悲的是,我仍然找不到我想要的答案,因为我想做的就是在我的Web应用程序中添加指向当前web.config的链接,并在编写代码时使用这些值,否则,添加一个app.config因为我的测试无法测试我的Web应用程序配置,所以这是我在开发应用程序时要测试的信息的一部分。但是,不要将测试与代码混合在一起是有道理的,但这有时很难做到。
EugenioMiró'17

Answers:


109

单元测试项目应具有自己的配置文件。

在测试项目上,可以选择“添加”,“新项目”,“应用程序配置文件”。

该文件的行为将与web.config完全相同,但是用于单元测试。


2
我已经尝试了您的建议,我在测试项目中添加了一个新的配置文件。连接字符串到位,但是在运行测试时,我总是在一行上看到null var sqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings [“ SqlServer”]。ConnectionString); 我可能会缺少什么?
ilivewithian

1
FWIW,我发布了对类似问题的回复(stackoverflow.com/a/47355610/183174)[here]。要点是,您可以让VS覆盖在构建测试项目时复制的配置文件。
LostNomad311年

14

您可以使用从任何位置加载web.config或app.config OpenMappedExeConfiguration。确保System.Configuration已添加到项目的参考。

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap()
fileMap.ExeConfigFilename = @"c:\my-web-app-location\web.config"

Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
string connectionString = config.AppSettings.Settings["ConnectionString"].Value;

这是web.config,非常标准。

<?xml version="1.0"?>
<configuration>
  <configSections>
  </configSections>
  <appSettings>
    <add key="ConnectionString" value="Data Source=XXXX;Initial Catalog=XXX; Trusted_Connection=True;"/>
  </appSettings>
</configuration>

于2017-09-29更新

我上了一堂课,使从文件中读取AppSetitngs更容易。我从Zp Bappi那里得到了这个主意。

public interface IAppSettings
{
    string this[string key] { get; }
}

public class AppSettingsFromFile : IAppSettings
{
    readonly Configuration Config;

    public AppSettingsFromFile(string path)
    {
        var fileMap = new ExeConfigurationFileMap();
        fileMap.ExeConfigFilename = path;
        Config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
    }

    public string this[string key]
    {
        get
        {
            return Config.AppSettings.Settings[key].Value;
        }
    }
}

这是使用该类的方法。

IAppSettings AppSettings = new AppSettingsFromFile(@"c:\my-web-app-location\web.confg");
string connectionString = AppSettings["ConnectionString"];

7

将您的web.config文件复制到“ / bin”文件夹中,然后将其重命名为“ AppName.dll.config”。

其中“ AppName”-是结果程序集的名称。

我曾多次使用此技巧。


它对我不起作用。单元测试不会自动知道配置文件中的ConnectionString。我必须编写一些自定义代码才能从配置中读取它。
orad 2012年

2
在大多数情况下,应像在已接受的答案中那样添加简单的app.config。这是一些怪异配置的攻击(例如TestDriven中的“临时测试”)
Alex

它对我有用,它在测试项目的.proj文件中具有以下设置:<ItemGroup> <None Include =“ .. \ MyProject \ Web.config”> <Link> $(TargetFileName).config </ Link> <CopyToOutputDirectory> PreserveNewest </ CopyToOutputDirectory> </ None> </ ItemGroup>谢谢
orad 2012年

4

您将希望结果定义明确且可重复。为此,您需要对已知数据进行处理,以便可以清楚地定义正常情况和边界情况。在我的工作中,这始终是特定的服务器和数据集,因此单元测试模块内置了连接字符串。其他人则更喜欢在单元测试项目中使用连接字符串。我从未见过有人建议使用该网站的配置文件!(开发或其他)


1
这很有意义,那么将连接字符串放入我的应用程序进行测试的解决方案是什么?
ilivewithian

硬编码特定于您的测试环境的连接字符串(这有难闻的气味,但实际上非常实用,因为它与可部署的代码无关),或者按照Gerrie的建议使用专门为您的单元测试模块定义的配置文件。
Mark Brittingham

1
只是强调:我不是暗示你永远硬编码在代码中的数据库连接字符串,将被部署!我在始终用于单元测试的特定服务器上具有特定数据库。在测试之前,我运行一个脚本来确保db处于适当的状态。
Mark Brittingham


1

如果需要连接字符串,则无需编写单元测试(假设您正在使用连接字符串进入数据库)。单元测试不应与外部环境交互。您将希望在每次签入后都运行它们,以便它们以光速运行。

对于单元测试,您将需要将代码与数据库隔离。修改测试(以及必要时要测试的代码),以使您无需进入数据库进行测试。


1
那么,您是否建议我不要测试任何访问数据库的代码?
ilivewithian

3
不能。您的代码绝不能访问数据库(除非您正在编写数据库框架)。而是将对象传递给代码,该对象可以访问数据库。在单元测试中,模拟该对象,在生产中,使用实际的数据库访问类。
Serhat Ozgel,09年

23
我只是完全不同意这一点。它使单元测试脱离了实际的动手工具来改善代码的范围,并将其变成了由人为边界所包围的抽象。
Mark Brittingham

3
可以使用集成测试而不是单元测试来测试数据库功能。而且您可以将它们与单元测试分开,这样,您可以在每次签入后运行单元测试,并在每次每日构建后或需要时运行集成测试。
Serhat Ozgel,09年

6
我必须在这里同意马克·布里廷瑟姆的观点。我知道纯粹主义者会说您需要模拟数据,但是如果您的大多数代码都在迭代从数据库返回的数据集行,该怎么办?如果您有一个模拟对象,那么您只是在测试仅用于单元测试目的的“虚构”代码。
亨利·邱
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.