Nik*_*hil 6 c# unit-testing moq mocking
我在config.json文件中有一个如下列表
{
"foo": {
"bar": [
"1",
"2",
"3"
]
}
}`
Run Code Online (Sandbox Code Playgroud)
我可以使用以下命令在运行时获取列表
Configuration.GetSection("foo:bar").Get<List<string>>()
Run Code Online (Sandbox Code Playgroud)
我想模拟configuration.GetSection
编写单元测试。
以下语法失败
mockConfigRepo
.SetupGet(x => x.GetSection("reportLanguageSettings:reportLanguageList").Get<List<string>>())
.Returns(reportLanguages);
Run Code Online (Sandbox Code Playgroud)
Aha*_*hak 16
我能够使用 ConfigurationBuilder 解决它。希望这会有所帮助
var appSettings = @"{""AppSettings"":{
""Key1"" : ""Value1"",
""Key2"" : ""Value2"",
""Key3"" : ""Value3""
}}";
var builder = new ConfigurationBuilder();
builder.AddJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(appSettings)));
var configuration= builder.Build();
Run Code Online (Sandbox Code Playgroud)
您可以尝试其他方法。例如,您可以尝试在您的测试类中创建一个 ConfigurationBuilder 实例:
string projectPath = AppDomain.CurrentDomain.BaseDirectory.Split(new String[] { @"bin\" }, StringSplitOptions.None)[0];
IConfiguration config = new ConfigurationBuilder()
.SetBasePath(projectPath)
.AddJsonFile("config.json")
.Build();
Run Code Online (Sandbox Code Playgroud)
注意:请不要忘记将您的 config.json 文件也添加到您的测试项目中。
小智 9
一般来说,如果您在根级别有一个键/值并且您想模拟这段代码:
var threshold = _configuration.GetSection("RootLevelValue").Value;
Run Code Online (Sandbox Code Playgroud)
你可以做:
var mockIConfigurationSection = new Mock<IConfigurationSection>();
mockIConfigurationSection.Setup(x => x.Key).Returns("RootLevelValue");
mockIConfigurationSection.Setup(x => x.Value).Returns("0.15");
_mockIConfiguration.Setup(x => x.GetSection("RootLevelValue")).Returns(mockIConfigurationSection.Object);
Run Code Online (Sandbox Code Playgroud)
如果键/值不在根级别,并且您想要模拟这样的代码:
var threshold = _configuration.GetSection("RootLevelValue:SecondLevel").Value;
Run Code Online (Sandbox Code Playgroud)
你也必须嘲笑Path
:
var mockIConfigurationSection = new Mock<IConfigurationSection>();
mockIConfigurationSection.Setup(x => x.Path).Returns("RootLevelValue");
mockIConfigurationSection.Setup(x => x.Key).Returns("SecondLevel");
mockIConfigurationSection.Setup(x => x.Value).Returns("0.15");
Run Code Online (Sandbox Code Playgroud)
依此类推第三级:
var threshold = _configuration.GetSection("RootLevelValue:SecondLevel:ThirdLevel").Value;
Run Code Online (Sandbox Code Playgroud)
你也必须嘲笑Path
:
var mockIConfigurationSection = new Mock<IConfigurationSection>();
mockIConfigurationSection.Setup(x => x.Path).Returns("RootLevelValue:SecondLevel");
mockIConfigurationSection.Setup(x => x.Key).Returns("ThirdLevel");
mockIConfigurationSection.Setup(x => x.Value).Returns("0.15");
Run Code Online (Sandbox Code Playgroud)
小智 9
只是补充一下艾哈迈德·伊沙克的答案。将实际对象转换为 JSON 会清理代码并且类型受到尊重。避免字符串拼写错误等。
var appSettings = JsonConvert.SerializeObject(new
{
Security = new SecurityOptions {Salt = "test"}
});
var builder = new ConfigurationBuilder();
builder.AddJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(appSettings)));
var configuration = builder.Build();
Run Code Online (Sandbox Code Playgroud)
我遇到了同样的问题,发现我需要为数组中的每个元素以及数组节点本身创建一个模拟IConfigurationSection,然后将父节点设置为返回子代,并让子代返回其值。在OP示例中,它看起来像这样:
var oneSectionMock = new Mock<IConfigurationSection>();
oneSectionMock.Setup(s => s.Value).Returns("1");
var twoSectionMock = new Mock<IConfigurationSection>();
twoSectionMock.Setup(s => s.Value).Returns("2");
var fooBarSectionMock = new Mock<IConfigurationSection>();
fooBarSectionMock.Setup(s => s.GetChildren()).Returns(new List<IConfigurationSection> { oneSectionMock.Object, twoSectionMock.Object });
_configurationMock.Setup(c => c.GetSection("foo:bar")).Returns(fooBarSectionMock.Object);
Run Code Online (Sandbox Code Playgroud)
PS:我使用的是Moq,因此请转换为您选择的模拟库。
PPS如果您对这种方法为什么能奏效,不可模仿的Get()方法做什么或比OP具有更复杂的方案感兴趣,则阅读此类可能会有所帮助:https : //github.com/aspnet/Extensions/blob/版本/2.1/src/Configuration/Config.Binder/src/ConfigurationBinder.cs
归档时间: |
|
查看次数: |
3593 次 |
最近记录: |