9

我有一个类库,我想使用Microsofts单元测试框架进行单元测试。我想测试的一些类是使用应用程序设置进行配置的。这些设置在Settings.settings文件中定义,该文件具有应用范围和合适的默认值。当应用程序使用库时,可以在App.Config文件中重写这些设置。如果不是,则使用默认值。这正是我想要的。在单元测试中修改应用程序设置

在我的一些测试案例中,我想测试设置值的特殊组合,但我不知道如何更改单元测试代码中待测类所见的值。这些设置将始终使用代码生成的类的属性加载它们的默认值。

在我的库类我访问的设置是这样的:

var mySetting1 = Settings.Default.MySetting1; 
var mySetting2 = Settings.Default.MySetting2; 

如何在单元测试修改这些设置之前,设置由类测试访问?使单元测试可访问的内部设置类不能解决问题,因为这些设置具有应用程序范围,并且是设置类的只读属性。

回答

14

洞穴探险到ApplicationSettingsBase以及相关的类后,我想出了这个解决我的问题。不是特别漂亮,但它确实完成了工作。

代码生成的设置类在类库项目的内部,它必须可供单元测试项目访问。在类库项目中将[assembly: InternalsVisibleTo("UnitTestAssemblyName")]属性添加到AssemblyInfo.cs

访问值时,设置将从设置类上的属性延迟加载。第一步是对设置进行“虚拟”读取以强制执行此延迟加载。单元测试时,您希望避免在一个测试中更改设置值以影响另一个测试,因此需要在延迟加载它们之前“重置”设置。这可以使用Reload()方法完成。此代码放置在测试初始化​​方法中:

Settings.Default.Reload(); 
var dummy = Settings.Default.MySetting1; 

基础值现在存在,可以在每种测试方法中进行设置。请记住,使用正确的类型生成的代码干将会做投:

Settings.Default.PropertyValues["MyStringSetting1"].PropertyValue = "Foobar"; 
Settings.Default.PropertyValues["MyDoubleSetting2"].PropertyValue = 3.1416D; 
+0

+1用于重新加载+属性访问器解决方法。 – 2013-03-13 15:08:35

+0

非常感谢你,我从来没有想到过。 – 2016-02-18 19:47:03

5

我会在Settings类的周围创建一个包装类,然后传递该包装。然后你可以轻松地嘲笑你的设置类。

我唯一能想到的另一件事是轻量化和轻松模拟选项,使您的设置文件实现反映所有设置的界面。对于调用者来说这并没有太大的不同,但添加新设置时您不需要执行任何操作。

这两个都不是很好,而且为自动生成的代码做这件事是一件很痛苦的事情,但看起来就是我们所坚持的,只要我能分辨出你是否真的想删除依赖关系设置文件。

E.g.对于包含字符串应用程序设置一个设置文件和一个int用户设置:

internal sealed partial class Settings : IMySettings { 

    /* 
    * here be auto-generate code (and dragons!) 
    */ 
} 

internal interface IMySettings 
{ 
    string ApplicationSetting 
    { 
     get; 
    } 

    string UserSetting 
    { 
     get; 
     set; 
    } 
} 
+0

我宁愿避免注射的设置,因为我有很多库和依赖注入的数量增长了很多,因为我动起来的依赖性层次结构。此外,由Visual Studio生成的代码包装类是乏味的。我希望有一个不是纯粹的DI的解决方案,但可以在.NET中使用应用程序设置。 – 2010-09-15 15:51:43

+0

不幸的是,我不认为有一个,你能做的最好的就是设置用户设置,但是应用程序设置不会在文件外改变。我现在唯一能想到的其他事情就是使用一个界面,稍微轻一些,但仍然像纯粹的DI一样。 – 2010-09-16 10:47:28