操作 app.config 文件进行单元测试
我已将 C# 应用程序的 NUnit 测试隔离在名为 Tests.dll 的程序集中。关联的配置文件称为 Tests.dll.config。这是 Nunit 使用的,而不是我的应用程序的实际配置文件。它看起来像这样(仅显示几个配置选项,还有更多):
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="useHostsFile" value="true" />
<add key="importFile" value="true" />
</appSettings>
</configuration>
为了确保我的应用程序经过彻底测试,我需要在测试之间更改配置选项。 运行几次测试后,我想向文件添加一些新的配置值,并供后续测试使用。我需要添加什么代码才能做到这一点?
I have isolated the NUnit tests for my C# app in an assembly called Tests.dll. The associated configuration file is called Tests.dll.config. This is what Nunit uses rather than my app's actual config file. It looks like this (only showing a couple of config options there are lots more):
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="useHostsFile" value="true" />
<add key="importFile" value="true" />
</appSettings>
</configuration>
To ensure my app is thoroughly tested, I will need to change config options between tests.
After I have run a couple of tests, I would like to add some new config values to the file and have these used by subsequent tests. What code would I need to add do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我有一个案例,我的配置读取器是使用惰性单例模式实现的,仅读取一次。这样更改 app.config 是不够的,因为该值已经从原始配置文件中读取。
但是,单例不会跨越应用程序域边界,您可以为您创建的新应用程序域指定 app.config。因此,我能够通过以下方式测试惰性单例应用程序设置:
对于非静态调用,请参阅 https://learn.microsoft.com/en-us/dotnet/api/system.appdomain?view=netframework-4.7.2
I had a case where my config readers were implemented using Lazy singleton pattern to read only once. Such that changing the app.config was not sufficient as the value was already read from the original configuration file.
The singleton does not cross appdomain boundaries however, and you can specify the app.config for new app domains that you create. So I was able to test the Lazy singleton app settings with:
For non-static calls see the example of using CreateInstanceAndUnwrap at https://learn.microsoft.com/en-us/dotnet/api/system.appdomain?view=netframework-4.7.2
我建议实现一个具有 useHostsFile 和 importFile 属性的接口 IConfig。然后,我将删除对此文件的所有直接依赖项,但实现 IConfig 的 ConfigDefault 类除外。在此实现中,您加载正常的配置文件。对于每个测试,您可以实现另一个也继承自 IConfig 的类。我建议使用依赖注入。 Ninject 是免费且易于使用的。
I recommend to implement a interface IConfig with properties useHostsFile and importFile. Then i would remove all direct dependecies to this file except in the Class ConfigDefault which implements IConfig. In this implementation you load your normal config file. For each test you can implement another Class which also inherits from IConfig. I suggest to use a Dependecy Injection. Ninject is free and easy to use.
我使用这段代码:
I use this code:
这是我对这一挑战的两分钱。简单地说,创建一个新类 AppSettings 作为抽象层。在正常操作下,它只会从应用程序配置文件中读取设置。但是单元测试可以基于每个线程覆盖设置,从而允许单元测试与不同的设置并行执行。
在应用程序代码中,使用静态属性访问设置:
在单元测试中,可以选择覆盖选定的设置:
注意:由于 AppSettings 类的所有方法都声明为内部方法,因此有必要使用以下属性使它们对单元测试程序集可见:
[程序集:InternalsVisibleTo("<程序集名称>, PublicKey=<公钥>")]
Here is my two cents to this challenge. Simply, create a new class AppSettings as an abstraction layer. Under normal operations it will simply read the settings from the application configuration file. But unit tests can override the settings on a per thread basis allowing for unit tests to execute in parallel with different settings.
In the application code, access settings using the static properties:
In unit tests, optionally override selected settings:
NOTE: As all methods of the AppSettings class are declared as internal it is necessary to make them visible to the unit test assembly using the attribute:
[assembly: InternalsVisibleTo("<assembly name>, PublicKey=<public key>")]