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 */)))