16

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

在我的一些测试用例中,我想测试设置值的特殊组合,但我不知道如何从单元测试代码中更改被测类看到的值。这些设置将始终从代码生成类的属性中加载其默认值。

在我的库类中,我访问如下设置:

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

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

4

2 回答 2

20

在深入研究ApplicationSettingsBase相关类之后,我想出了解决我问题的方法。不是特别漂亮,但它确实可以完成工作。

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

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

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

基础值现在存在并且可以在每个测试方法中设置。请记住使用正确的类型,因为代码生成的 getter 会进行强制转换:

Settings.Default.PropertyValues["MyStringSetting1"].PropertyValue = "Foobar";
Settings.Default.PropertyValues["MyDoubleSetting2"].PropertyValue = 3.1416D;
于 2010-09-17T10:45:59.050 回答
5

我会围绕Settings该类创建一个包装器类,然后传递该包装器。然后你可以轻松地模拟你的设置类。

我唯一能想到的另一件事是更轻量级且更容易模拟的选项,使您的设置文件实现一个反映所有设置的接口。对于调用者来说并没有太大的不同,但是在添加新设置时你要做的事情会更少。

两者都不是很棒,而且必须为自动生成的代码做这件事很痛苦,但据我所知,如果你真的想删除对设置文件的依赖,这似乎就是我们所坚持的。

例如,对于包含字符串应用程序设置和 int 用户设置的设置文件:

internal sealed partial class Settings : IMySettings {

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

internal interface IMySettings
{
    string ApplicationSetting
    {
        get;
    }

    string UserSetting
    {
        get;
        set;
    }
}
于 2010-09-15T15:28:04.110 回答