C# 模拟自定义配置类
我有一个自定义类用于读取Azure Function App v2中的配置值:C# 模拟自定义配置类,c#,asp.net-core,moq,xunit,azure-function-app,C#,Asp.net Core,Moq,Xunit,Azure Function App,我有一个自定义类用于读取Azure Function App v2中的配置值: public class Config { public string Key1 { get; set; } public string Key2 { get; set; } public Config() { this.Key1 = Environment.GetEnvironmentVariable("abc"); this.Key2 = Envi
public class Config
{
public string Key1 { get; set; }
public string Key2 { get; set; }
public Config()
{
this.Key1 = Environment.GetEnvironmentVariable("abc");
this.Key2 = Environment.GetEnvironmentVariable("xyz");
}
}
我已经在Startup.cs
类的Configure
方法中注册了它,如下所示:
builder.Services.AddSingleton((s) =>
{
return new Config();
});
现在,当我试图模拟这个Config.cs
类并设置其键的值时,它抛出错误:
var mockConfiguration = new Mock<Config>();
mockConfiguration.Setup(m => m.Key1).Returns("value");
var mockConfiguration=new Mock();
Setup(m=>m.Key1).返回(“值”);
我使用
XUnit
作为测试框架,使用MOQ
进行模拟。如果我不想为我的配置类创建一个接口,还有什么方法可以模拟它呢?这源于一个初始设计问题
Config
类与实现问题紧密耦合
Environment.GetEnvironmentVariable
在隔离测试时不存在,并导致异常
正如评论中准确指出的,您应该利用配置模块并注册配置,而不是紧密耦合到环境
类
参考:
并将IOptions
显式注入subject函数
private readonly Config config;
//ctor
public MyFunction(IOptions<Config> options) {
config = options.Value;
//...
}
因此,允许对功能进行隔离测试,而不会因实现问题而产生不必要的副作用
//Arrange
var mockConfiguration = new Config() {
Key1 = "value"
};
var subject = new MyFunction(mockConfiguration);
//...
当然,它不会让您模拟它,因为属性是非虚拟的(我假设通过阅读错误消息,您应该知道这一点)。通过继承类(或接口)并用模拟代码重写/实现属性,模拟可以工作。无论哪种方式,您都应该重构类以使其更易于重构,而接口是实现这一点的一种方法。如果您开始在代码的其他部分更新或使用静态类,您将越来越多地遇到此类问题,原因是软件设计不好。此外,不清楚您为什么不使用选项模式(
IOptions
class with.Configure(options=>options.Key1=Environment.GetEnvironmentVariable(“abc”))
,然后将IOptions
)注入到您的类中,您将永远不会出现这种情况
private readonly Config config;
//ctor
public MyFunction(IOptions<Config> options) {
config = options.Value;
//...
}
builder.Services.Configure<Config>(options => {
options.Key1 = Environment.GetEnvironmentVariable("abc");
options.Key2 = Environment.GetEnvironmentVariable("xyz");
});
builder.Services.AddSingleton((s) => {
return s.GetRequiredService<IOptions<Config>>().Value;
});
//ctor
public MyFunction(Config config) {
//...
}
//Arrange
var mockConfiguration = new Config() {
Key1 = "value"
};
var subject = new MyFunction(mockConfiguration);
//...