我想为MSTest项目中的单元测试创建自定义appsettings.json文件。我称它为[[testsettings.json。我在主项目中使用存储库模式,因此在ASP.NET端有一个IUnitOfWork和UnitOfWork声明为Singleton。这样就可以访问各种存储库。
此UnitOfWork确实依赖一些配置变量,因此我使用appsettings.json来存储它们。因此,UnitOfWork的构造函数接受一个IConfiguration变量,该变量通过依赖项注入以及ASP.NET中所有这些聪明的东西进行解析。但是,在MSTest项目中没有这样的。因此,我需要自己创建IConfiguration对象以使用构造函数。我查看了这些StackOverflow链接中的代码:
How can I create an instance of IConfiguration locally?
Populate IConfiguration for unit tests
How can I add a custom JSON file into IConfiguration?
Using IConfiguration in C# Class Library
但是,问题在于,在NET Core 3.1中,我不能使用此功能:
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath([PATH_WHERE_appsettings.json_RESIDES])
.AddJsonFile("appsettings.json")
.Build();
因此,我采取了以字符串形式读取JSON文件,使用Newtonsoft.Json将其转换为Dict<string, string>
,然后将其解析为配置文件的方法。它没有经过优化,我必须使用不同的appsettings.json结构,因为我无法将JSON对象解析为字符串字典。所以我必须这样做:
{ "var1": "abc", "var2": "def", "var3": "hij" }
代替此:
{ "obj1": { "var1": "abc", "var2": "def", "var3": "hij" } }
这是我的实现:
//setup logger //------------------- var loggerFactory = LoggerFactory.Create(builder => { builder .AddFilter("Microsoft", LogLevel.Warning) .AddFilter("System", LogLevel.Warning) .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug); }); testLogger = loggerFactory.CreateLogger<LocationRecordManagerTests>(); testLogger.LogInformation("Init FileName of unit tests"); //setup config file //------------------- //get file path string liveFolder = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName; string projectFolder = Directory.GetParent(liveFolder).FullName; string filePath = Path.Combine(projectFolder, "testsettings.json"); //get json as string data string jsonString = File.ReadAllText(filePath); Dictionary<string, string> jsonDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString); //build config file var configBuilder = new ConfigurationBuilder(); configBuilder.AddInMemoryCollection(jsonDict); var configFile = configBuilder.Build(); //test - this works //object value = configFile.GetSection("var1"); //create UnitOfWork //------------------- testUnitOfWork = new UnitOfWork(testLogger, configFile);
有人知道如何更好地做到这一点吗?
Configuration in ASP.NET Core
的示例bind-hierarchical-configuration-data-using-the-options-pattern。无论将配置放在appsettings.json
还是testsettings.json
中,您都可以将它们绑定到名为UnitOfWorkModel的模型中,下面的示例。
appsettings.json{
"Logging": {
"LogLevel": {
"Default": "Information"
}
},
"UnitOfWork": {
"var1": "abc",
"var2": "def",
"var3": "hij"
}
}
testsettings.json
{ "var1": "abc", "var2": "def", "var3": "hij" }
您可以首先声明用于配置的绑定模型
public class UnitOfWorkModel { public string Var1 { get; set; } public string Var2 { get; set; } public string Var3 { get; set; } }
然后,在.NET Core启动时从本机对象绑定到UnitOfWorkModel中>IConfiguration
public Startup(IConfiguration configuration)
{
IConfigurationSection section = configuration.GetSection("UnitOfWork");
IConfiguration configuration = section as IConfiguration;
IEnumerable<IConfigurationSection> items = configuration.GetSection("UnitOfWork").GetChildren();
// items.Count() == 3
Dictionary<string, string> dict = items.ToDictionary(o => o.Key, o => o.Value);
// dict.Count() == 3
var unitOfWorkModel = new UnitOfWorkModel();
section.Bind(unitOfWorkModel);
// unitOfWorkModel.Var1 == "abc";
// unitOfWorkModel.Var2 == "def";
// unitOfWorkModel.Var3 == "hij";
}
或者,通过单元测试来测试绑定结果(这是.NET Core的xUnit
测试框架的示例)
[xUnit]
public void BindTest()
{
IConfigurationRoot root = new ConfigurationBuilder()
.AddJsonFile("testsettings.json")
.Build();
IConfiguration configuration = root as IConfiguration;
Assert.NotNull(configuration);
var unitOfWorkModel = new UnitOfWorkModel();
root.Bind(unitOfWorkModel);
Assert.Equals("abc", unitOfWorkModel.Var1);
Assert.Equals("def", unitOfWorkModel.Var2);
Assert.Equals("hij", unitOfWorkModel.Var3);
}
两种方法都可以在超级接口中正常工作。IConfiguration