简体   繁体   English

C# 如何模拟 Configuration.GetSection(“foo:bar”).Get <List<string> &gt;()

[英]C# how to mock Configuration.GetSection(“foo:bar”).Get<List<string>>()

I have a list like following in config.json file `我在 config.json 文件中有一个如下所示的列表`

{
  "foo": {
    "bar": [
      "1",
      "2",
      "3"
    ]
  }
}`

I am able to get the list at run-time using我能够在运行时使用

Configuration.GetSection("foo:bar").Get<List<string>>()

I want to mock the configuration.GetSection to write unit test.我想模拟configuration.GetSection来编写单元测试。

Following syntax is failing以下语法失败

mockConfigRepo
    .SetupGet(x => x.GetSection("reportLanguageSettings:reportLanguageList").Get<List<string>>())
    .Returns(reportLanguages);

I've encountered same issue and found that I needed to create a mock IConfigurationSection for every element in the array, as well as the array node itself, and then setup the parent node to return children, and children to return their values.我遇到了同样的问题,发现我需要为数组中的每个元素以及数组节点本身创建一个模拟 IConfigurationSection,然后设置父节点返回子节点,子节点返回它们的值。 In OP example, it would look like this:在 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);

PS I'm using Moq, so please translate to your mock library of choice. PS 我正在使用 Moq,所以请转换为您选择的模拟库。

PPS If you are interested in why this ends up working, what unmockable Get() method does, or have a more complex scenario than OP, reading this class may be helpful: https://github.com/aspnet/Extensions/blob/release/2.1/src/Configuration/Config.Binder/src/ConfigurationBinder.cs PPS 如果您对这最终起作用的原因感兴趣,不可模拟的 Get() 方法有什么作用,或者有比 OP 更复杂的场景,阅读本课程可能会有所帮助: https : //github.com/aspnet/Extensions/blob/ release/2.1/src/Configuration/Config.Binder/src/ConfigurationBinder.cs

I was able to solve it using ConfigurationBuilder.我能够使用 ConfigurationBuilder 解决它。 Hope this will help希望这会有所帮助

  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();

You can try alternative ways.您可以尝试其他方法。 For example, you can try to create an instance of ConfigurationBuilder in your test class:例如,您可以尝试在您的测试类中创建一个 ConfigurationBuilder 实例:

string projectPath = AppDomain.CurrentDomain.BaseDirectory.Split(new String[] { @"bin\" }, StringSplitOptions.None)[0];
IConfiguration config = new ConfigurationBuilder()
   .SetBasePath(projectPath)
   .AddJsonFile("config.json")
   .Build();

Note : Please don't forget to add your config.json file to your test project too.注意:请不要忘记将您的 config.json 文件也添加到您的测试项目中。

In general, if you have a key/value at the root level and you want to mock this piece of code:一般来说,如果您在根级别有一个键/值并且您想模拟这段代码:

var threshold = _configuration.GetSection("RootLevelValue").Value;

you can do:你可以做:

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);

If the key/value is not at the root level, and you want to mock a code that is like this one:如果键/值不在根级别,并且您想要模拟这样的代码:

var threshold = _configuration.GetSection("RootLevelValue:SecondLevel").Value;

you have to mock Path as well:您还必须模拟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");

and so on for the third level:依此类推第三级:

var threshold = _configuration.GetSection("RootLevelValue:SecondLevel:ThirdLevel").Value;

you have to mock Path as well:您还必须模拟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");

Just to add on Ahamed Ishak answer.只是为了补充 Ahamed Ishak 的回答。 Convert actual objects to JSON would clean up the code and types are respected.将实际对象转换为 JSON 会清理代码并尊重类型。 Avoid string typo errors, etc.避免字符串拼写错误等。

        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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C# 为对象列表创建 Mock Configuration.GetSection(“Section:SubSection”) - C# Create Mock Configuration.GetSection(“Section:SubSection”) for objects list 如何使用 FakeItEasy 语法模拟 configuration.GetSection? - How to mock configuration.GetSection with FakeItEasy syntax? .Net Core Configuration.GetSection()。获取&lt;&gt;()不绑定 - .Net Core Configuration.GetSection().Get<>() not binding Configuration.GetSection(“的connectionStringName”)。获取 <?> 总是为空 - Configuration.GetSection(“ConnectionStringName”).Get<?> always null Configuration.GetSection()轻松获取原始字符串值,但不获取复杂值 - Configuration.GetSection() easily gets primitive string values but not complex values Configuration.GetSection返回null值 - Configuration.GetSection returns null value 为什么 static Configuration.GetSection() 不可用? - Why is static Configuration.GetSection() not available? ConfigurationManager.GetSection和Configuration.GetSection有什么区别? - What is Difference between ConfigurationManager.GetSection and Configuration.GetSection? configuration.getValue 或 configuration.getsection 总是返回 null - configuration.getValue or configuration.getsection always returns null Configuration.GetSection 从 appsetting.json 获取值但 Configuration.GetSection.Bind 总是返回 null - Configuration.GetSection gets value from appsetting.json but Configuration.GetSection.Bind always returns null
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM