简体   繁体   English

如何使用 Moq 模拟 IConfiguration?

[英]How do I mock IConfiguration with Moq?

How do I mock code like this in my unit test.如何在单元测试中模拟这样的代码。 I'm using xUnit and Moq in asp.net core 5. I'm new to xUnit and Moq.我在 asp.net 核心 5 中使用 xUnit 和 Moq。我是 xUnit 和 Moq 的新手。

var url = configuration.GetSection("AppSettings").GetSection("SmsApi").Value;

The configuration object is already injected into the constructor.配置 object 已经注入到构造函数中。

This is what I currently have in my unit test class这就是我目前在单元测试 class 中的内容

public class UtilityTests
{
    private readonly Utility sut;

    public UtilityTests()
    {
        var mockConfig = new Mock<IConfiguration>();
        var mockConfigSection = new Mock<IConfigurationSection>();
        //mockConfigSection.Setup(x => x.Path).Returns("AppSettings");
        mockConfigSection.Setup(x => x.Key).Returns("SmsApi");
        mockConfigSection.Setup(x => x.Value).Returns("http://example.com");
        
        mockConfig.Setup(x => x.GetSection("AppSettings")).Returns(mockConfigSection.Object);
        
        sut = new Utility(mockConfig.Object);
    }

    [Fact]
    public void SendSmsShdReturnTrue()
    {
        var fixture = new Fixture();
        
        var result = sut.SendSms(fixture.Create<string>(), fixture.Create<string>());
        result.Should().BeTrue();
    }
}

Alternative approach tp introduce a class to represent section of the configuration, then use IOptions interface to inject it to the constructor.替代方法 tp 引入一个 class 来表示配置部分,然后使用IOptions接口将其注入构造函数。

Your tests then become simple to configure without mocking, just create an instance and pass it to the constructor.然后,您的测试变得易于配置,无需 mocking,只需创建一个实例并将其传递给构造函数。

Something like below:如下所示:

class SmsApiSettings
{
    public string Url { get; set; }
}

Register during startup启动时注册

services.Configure<SmsApiSettings>(Configuration.GetSection("SmsApi"));

Constructor构造函数

public class ClassUnderTest
{
    private readonly SmsApiSettings _smsApiSettings;

    public ClassUnderTest(IOptions<> smsOptions)
    {
        _smsApiSettings = smsOptions.Value;
    }
}

Tests测试

var settings = new SmsApiSettings { Url = "http://dummy.com" };
var options = Options.Create(settings);

var sut = new ClassUnderTest(options);

Enjoy happy life without mocks;)享受没有嘲笑的幸福生活;)

The truth is that the IConfiguration should not be mocked.事实是不应该嘲笑IConfiguration Instead it should be built .相反,它应该被构建

via dictionary通过字典

Data数据

var configForSmsApi = new Dictionary<string, string>
{
    {"AppSettings:SmsApi", "http://example.com"},
};

Usage用法

var configuration = new ConfigurationBuilder()
    .AddInMemoryCollection(configForSmsApi)
    .Build();

via json file通过 json 文件

Data数据

{
  "AppSettings": {
    "SmsApi": "http://example.com"
  }
}

Usage用法

var configuration = new ConfigurationBuilder()
    .AddJsonFile("smsapi.json", optional: false)
    .Build();

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM