Как мне имитировать конфигурацию значков с помощью Moq?

#c# #asp.net-core-mvc #moq #xunit #xunit.net

Вопрос:

Как мне имитировать подобный код в моем модульном тесте? Я использую xUnit и Moq в asp.net ядро 5. Я новичок в xUnit и Moq.

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

Объект конфигурации уже введен в конструктор.

Это то, что у меня сейчас есть в моем классе модульного тестирования

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

Комментарии:

1. Это AppSettings.json или web.config ? Образец файла был бы полезен.

2. Это .net core, поэтому настройки приложения.json

3. @plasteezy Сработало ли для вас какое-либо из предложенных решений?

Ответ №1:

Альтернативный подход заключается в том, чтобы ввести класс для представления раздела конфигурации, а затем использовать IOptions интерфейс для его введения в конструктор.

Затем ваши тесты станут простыми в настройке без насмешек, просто создайте экземпляр и передайте его конструктору.

Что-то вроде ниже:

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

Зарегистрируйтесь во время запуска

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

Конструктор

 public class ClassUnderTest
{
    private readonly SmsApiSettings _smsApiSettings;

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

Тесты

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

var sut = new ClassUnderTest(options);
 

Наслаждайтесь счастливой жизнью без насмешек 😉

Комментарии:

1. Мне нравится этот метод, это более элегантный способ справиться с ним. Спасибо @Fabio

Ответ №2:

Правда в том, что IConfiguration над ними не следует насмехаться. Вместо этого его следует построить.

через словарь

Данные

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

Использование

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

через файл json

Данные

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

Использование

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