首页 > 解决方案 > 如何模拟或设置通常在启动时设置为静态属性的单元测试的值?

问题描述

在我们的项目中,有一个类包含一堆静态字段,用于在内存中保存设置值:

public class MyConfigurationSettings
{
    public static string MySettingId { get; set; }
    
    public string MySettingProcessIdentifier
    {
        get { return MySettingId; }

        set { MySettingId = value; }
    }
}

我不知道为什么会这样——那已经消失在时间的迷雾中了。此对象在启动时从设置文件中填充。

var defaultConfiguration = new MyConfigurationSettings();
configuration.GetSection("MyConfiguration").Bind(defaultConfiguration);

但是,我现在需要编写一个依赖于这些值的单元测试。该对象可用于我的测试:

TypeId = MyConfigurationSettings.MySettingId

但是该值始终为空(对于 int 或为零),并且大多数测试需要检查代码使用的设置值。

我看过使用 ConfigurationBuilder 但唯一有用的选项似乎是加载一个 json 文件,这对于单元测试来说并不好,我不知道如何绑定它。

如何为单元测试填充此对象?

标签: c#unit-testingconfigurationstartup

解决方案


当你的项目开始时,应该在某处定义一个根,它告诉应用程序在哪里寻找 appsettings.json(我假设你使用它,只要你在谈论配置)。例如:

var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)

当您运行测试时,您的执行目录不同并且文件未加载。这样你就可以:

  • 在测试构造函数中设置值(它是一个带有 getter 和 setter 的静态对象)
  • 测试项目启动时指向正确的文件json文件,路径会不同
  • 使用,如评论中建议的那样,以及我个人认为一个好的重构方式,即使用 DI 和 IOptions 的方式。在这种情况下,您可以将所需的设置注入您测试的类中。

您在启动中注册您的设置:

services.Configure<MySettings>(this.Configuration.GetSection("MySettings"));

在构造函数中的类中使用 DI:

public class MyClass{
 public MyClass(IOptions<MySettings> settings) { ... }
}

在您的测试中:

new MyClass(Options.Create<MySettings>(new MySettings(/* test settings here */)))

推荐阅读