.net 使用 NUnit 对 app.config 文件进行单元测试
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/168931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unit testing the app.config file with NUnit
提问by Dana
When you guys are unit testing an application that relies on values from an app.config file? How do you test that those values are read in correctly and how your program reacts to incorrect values entered into a config file?
当你们对依赖 app.config 文件中的值的应用程序进行单元测试时?您如何测试这些值是否被正确读取以及您的程序如何对输入到配置文件中的错误值做出反应?
It would be ridiculous to have to modify the config file for the NUnit app, but I can't read in the values from the app.config I want to test.
必须修改 NUnit 应用程序的配置文件是荒谬的,但我无法从要测试的 app.config 中读取值。
Edit: I think I should clarify perhaps. I'm not worried about the ConfigurationManager failing to read the values, but I am concerned with testing how my program reacts to the values read in.
编辑:我想我应该澄清一下。我并不担心 ConfigurationManager 无法读取值,但我关心的是测试我的程序如何对读入的值做出反应。
采纳答案by Mendelt
I usually isolate external dependencies like reading a config file in their own facade-class with very little functionality. In tests I can create a mock version of this class that implements and use that instead of the real config file. You can create your own mockup's or use a framework like moq or rhino mocks for this.
我通常隔离外部依赖项,例如在他们自己的外观类中读取配置文件,功能很少。在测试中,我可以创建这个类的模拟版本,它实现并使用它而不是真正的配置文件。您可以为此创建自己的模型或使用诸如 moq 或 rhino mocks 之类的框架。
That way you can easily try out your code with different configuration values without writing complex tests that first write xml-configuration files. The code that reads the configuration is usually so simple that it needs very little testing.
这样您就可以轻松地使用不同的配置值尝试您的代码,而无需编写首先编写 xml 配置文件的复杂测试。读取配置的代码通常非常简单,只需要很少的测试。
回答by Mendelt
You can modify your config section at runtime in your test setup. E.g:
您可以在运行时在测试设置中修改配置部分。例如:
// setup
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.Sections.Add("sectionname", new ConfigSectionType());
ConfigSectionType section = (ConfigSectionType)config.GetSection("sectionname");
section.SomeProperty = "value_you_want_to_test_with";
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("sectionname");
// carry out test ...
You can of course setup your own helper methods to do this more elegantly.
你当然可以设置你自己的辅助方法来更优雅地做到这一点。
回答by Pervez Choudhury
You can call the set method of ConfigurationManager.AppSettings to set the values required for that particular unit test.
您可以调用 ConfigurationManager.AppSettings 的 set 方法来设置该特定单元测试所需的值。
[SetUp]
public void SetUp()
{
ConfigurationManager.AppSettings.Set("SettingKey" , "SettingValue");
// rest of unit test code follows
}
When the unit test runs it will then use these values to run the code
当单元测试运行时,它将使用这些值来运行代码
回答by Steven A. Lowe
You can both read and write to the app.configfile with the ConfigurationManagerclass
您可以app.config使用ConfigurationManager该类读取和写入文件
回答by Tuomas Hietanen
I was facing similar problems with web.config.... I find an interesting solution. You can encapsulate configuration reading function, e.g. something like this:
我在 web.config 方面遇到了类似的问题......我找到了一个有趣的解决方案。您可以封装配置读取功能,例如这样的:
public class MyClass {
public static Func<string, string>
GetConfigValue = s => ConfigurationManager.AppSettings[s];
//...
}
And then normally use
然后正常使用
string connectionString = MyClass.GetConfigValue("myConfigValue");
but in unit test initialize "override" the function like this:
但在单元测试中初始化“覆盖”这样的函数:
MyClass.GetConfigValue = s => s == "myConfigValue" ? "Hi", "string.Empty";
More about it:
更多相关信息:
http://rogeralsing.com/2009/05/07/the-simplest-form-of-configurable-dependency-injection/
http://rogeralsing.com/2009/05/07/the-simplest-form-of-configurable-dependency-injection/
回答by Tuomas Hietanen
A more elegant solution is to use plain old dependency injection on the configuration settings themselves. IMHO this is cleaner than having to mock a configuration reading class/wrapper etc.
一个更优雅的解决方案是对配置设置本身使用普通的旧依赖注入。恕我直言,这比模拟配置读取类/包装器等要干净。
For example, say a class "Weather" requires a "ServiceUrl" in order to function (e.g. say it calls a web service to get the weather). Rather than having some line of code that actively goes to a configuration file to get that setting (whether that code be in the Weather class or a separate configuration reader that could be mocked as per some of the other responses), the Weather class can allow the setting to be injected, either via a parameter to the constructor, or possibly via a property setter. That way, the unit tests are extremely simple and direct, and don't even require mocking.
例如,假设类“天气”需要“ServiceUrl”才能运行(例如,它调用网络服务来获取天气)。与其让某行代码主动转到配置文件以获取该设置(无论该代码是在 Weather 类中还是在可以根据其他一些响应进行模拟的单独配置读取器中),Weather 类可以允许要注入的设置,可以通过构造函数的参数,也可以通过属性设置器。这样,单元测试非常简单和直接,甚至不需要模拟。
The value of the setting can then be injected using an Inversion of Control (or Dependency Injection) container, so the consumers of the Weather class don't need to explicitly supply the value from somewhere, as it's handled by the container.
然后可以使用控制反转(或依赖注入)容器注入设置的值,因此 Weather 类的使用者不需要从某处显式提供值,因为它是由容器处理的。
回答by yonexbat
That worked for me:
这对我有用:
public static void BasicSetup()
{
ConnectionStringSettings connectionStringSettings =
new ConnectionStringSettings();
connectionStringSettings.Name = "testmasterconnection";
connectionStringSettings.ConnectionString =
"server=localhost;user=some;database=some;port=3306;";
ConfigurationManager.ConnectionStrings.Clear();
ConfigurationManager.ConnectionStrings.Add(connectionStringSettings);
}
回答by Yuval
You can always wrap the reading-in bit in an interface, and have a specific implementation read from the config file. You would then write tests using Mock Objects to see how the program handled bad values. Personally, I wouldn't test this specific implementation, as this is .NET Framework code (and I'm assuming - hopefully - the MS has already tested it).
您始终可以将读入位包装在一个接口中,并从配置文件中读取特定的实现。然后您将使用 Mock Objects 编写测试以查看程序如何处理错误值。就个人而言,我不会测试这个特定的实现,因为这是 .NET Framework 代码(我假设 - 希望 - MS 已经对其进行了测试)。
回答by jakejgordon
System.Configuration.Abstractions is a thing of beauty when it comes to testing this kind of stuff.
System.Configuration.Abstractions 在测试这类东西时是一件很美妙的事情。
Here is the GitHub project site with some good examples: enter link description here
这是 GitHub 项目站点,其中包含一些很好的示例:在此处输入链接描述
Here is the NuGet site: https://www.nuget.org/packages/System.Configuration.Abstractions/
这是 NuGet 站点:https: //www.nuget.org/packages/System.Configuration.Abstractions/
I use this in almost all of my .NET projects.
我几乎在所有 .NET 项目中都使用它。
回答by user798990
Well, I just had the same problem... I wanted to test a BL project that is referenced from a web site . but i wanted to test the BL only. So in the pre-build event of the test project I copy the app.Config files into the bin\debug folder and reference them from the app.config ...
好吧,我刚刚遇到了同样的问题……我想测试一个从网站引用的 BL 项目。但我只想测试BL。因此,在测试项目的预构建事件中,我将 app.Config 文件复制到 bin\debug 文件夹中,并从 app.config 中引用它们...

