Populate IConfiguration for unit tests

前端 未结 5 755
别那么骄傲
别那么骄傲 2021-01-17 07:37

.NET Core configuration allows so many options to add values (environment variables, json files, command line args).

I just can\'t figure out and find an answer how

相关标签:
5条回答
  • 2021-01-17 08:03

    Would AddInMemoryCollection extension method help?

    You can pass a key-value collection into it: IEnumerable<KeyValuePair<String,String>> with the data you might need for a test.

    var builder = new ConfigurationBuilder();
    
    builder.AddInMemoryCollection(new Dictionary<string, string>
    {
         { "key", "value" }
    });
    
    0 讨论(0)
  • 2021-01-17 08:12

    You can use the following technique to mock IConfiguration.GetValue<T>(key) extension method.

    var configuration = new Mock<IConfiguration>();
    var configSection = new Mock<IConfigurationSection>();
    
    configSection.Setup(x => x.Value).Returns("fake value");
    configuration.Setup(x => x.GetSection("MySection")).Returns(configSection.Object);
    //OR
    configuration.Setup(x => x.GetSection("MySection:Value")).Returns(configSection.Object);
    
    0 讨论(0)
  • 2021-01-17 08:23

    The solution I went for (which answers the question title at least!) is to use a settings file in the solution testsettings.json and set it to "Copy Always".

        private IConfiguration _config;
    
        public UnitTestManager()
        {
            IServiceCollection services = new ServiceCollection();
    
            services.AddSingleton<IConfiguration>(Configuration);
        }
    
        public IConfiguration Configuration
        {
            get
            {
                if (_config == null)
                {
                    var builder = new ConfigurationBuilder().AddJsonFile($"testsettings.json", optional: false);
                    _config = builder.Build();
                }
    
                return _config;
            }
        }
    
    0 讨论(0)
  • 2021-01-17 08:24

    You can use MemoryConfigurationBuilderExtensions to provide it via a dictionary.

    using Microsoft.Extensions.Configuration;
    
    var myConfiguration = new Dictionary<string, string>
    {
        {"Key1", "Value1"},
        {"Nested:Key1", "NestedValue1"},
        {"Nested:Key2", "NestedValue2"}
    };
    
    var configuration = new ConfigurationBuilder()
        .AddInMemoryCollection(myConfiguration)
        .Build();
    

    The equivalent JSON would be:

    {
      "Key1": "Value1",
      "Nested": {
        "Key1": "NestedValue1",
        "Key2": "NestedValue2"
      }
    }
    

    The equivalent Environment Variables would be (assuming no prefix / case insensitive):

    Key1=Value1
    Nested__Key1=NestedValue1
    Nested__Key2=NestedValue2
    
    0 讨论(0)
  • 2021-01-17 08:24

    I prefer not to have my application classes dependent on IConfiguration. Instead I create a configuration class to hold the config, with a constructor that can initialise it from IConfiguration like this:

    public class WidgetProcessorConfig
    {
        public int QueueLength { get; set; }
        public WidgetProcessorConfig(IConfiguration configuration)
        {
            configuration.Bind("WidgetProcessor", this);
        }
        public WidgetProcessorConfig() { }
    }
    
    

    then in your ConfigureServices, you just have to do:

    services.AddSingleton<WidgetProcessorConfig>();
    services.AddSingleton<WidgetProcessor>();
    

    and for testing:

    var config = new WidgetProcessorConfig
    {
        QueueLength = 18
    };
    var widgetProcessor = new WidgetProcessor(config);
    
    0 讨论(0)
提交回复
热议问题