C# 如何为单元测试模拟或设置通常在启动时设置为静态属性的值?

C# 如何为单元测试模拟或设置通常在启动时设置为静态属性的值?,c#,unit-testing,configuration,startup,C#,Unit Testing,Configuration,Startup,在我们的项目中,有一个类包含一组静态字段,用于在内存中保存设置值: public class MyConfigurationSettings { public static string MySettingId { get; set; } public string MySettingProcessIdentifier { get { return MySettingId; } set { MySettingId = value

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

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文件,这对于单元测试来说并不太合适,我不知道如何绑定它


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

当您的项目启动时,应该在某个地方定义一个根,它告诉应用程序在哪里查找appsettings.json(我假设您使用它,只要您谈论的是配置)。例如:

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

  • 在测试构造函数中设置值(它是一个带有getter和setter的静态对象)
  • 当您的测试项目启动时,指向正确的json文件,路径将不同
  • 使用评论中提出的,以及我个人认为一个好的重构,用DI和IO期权的方式。在这种情况下,您可以将您想要的设置注入到您测试的类中
您可以在启动中注册设置:

services.Configure<MySettings>(this.Configuration.GetSection("MySettings"));
services.Configure(this.Configuration.GetSection(“MySettings”);
在构造函数中的类中使用DI:

public class MyClass{
 public MyClass(IOptions<MySettings> settings) { ... }
}
公共类MyClass{
公共MyClass(IOOptions设置){…}
}
在您的测试中:

new MyClass(Options.Create<MySettings>(new MySettings(/* test settings here */)))
newmyclass(Options.Create(新建MySettings(/*此处测试设置*/))

为什么不使用选项模式并注入
IOptions
,然后将其模拟为SUT?甚至在测试开始时安排一个值
new MyClass(Options.Create<MySettings>(new MySettings(/* test settings here */)))