Я чувствую, что здесь не хватает чего-то действительно очевидного. У меня есть классы, требующие ввода параметров с использованием шаблона .Net Core IOptions (?). Когда я перехожу к модульному тесту этого класса, я хочу поиздеваться над различными версиями опций для проверки функциональности класса. Кто-нибудь знает, как правильно имитировать / создавать / заполнять IOptions вне класса Startup?
Вот несколько примеров классов, с которыми я работаю:
Параметры / Параметры Модель
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace OptionsSample.Models
{
public class SampleOptions
{
public string FirstSetting { get; set; }
public int SecondSetting { get; set; }
}
}
Тестируемый класс, который использует настройки:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OptionsSample.Models
using System.Net.Http;
using Microsoft.Extensions.Options;
using System.IO;
using Microsoft.AspNetCore.Http;
using System.Xml.Linq;
using Newtonsoft.Json;
using System.Dynamic;
using Microsoft.Extensions.Logging;
namespace OptionsSample.Repositories
{
public class SampleRepo : ISampleRepo
{
private SampleOptions _options;
private ILogger<AzureStorageQueuePassthru> _logger;
public SampleRepo(IOptions<SampleOptions> options)
{
_options = options.Value;
}
public async Task Get()
{
}
}
}
Модульный тест в сборке, отличной от других классов:
using OptionsSample.Repositories;
using OptionsSample.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
namespace OptionsSample.Repositories.Tests
{
public class SampleRepoTests
{
private IOptions<SampleOptions> _options;
private SampleRepo _sampleRepo;
public SampleRepoTests()
{
//Not sure how to populate IOptions<SampleOptions> here
_options = options;
_sampleRepo = new SampleRepo(_options);
}
}
}
IOptions<T>
вас есть только издеватьсяValue
вернуть класс вы хотитеОтветы:
Вам необходимо вручную создать и заполнить
IOptions<SampleOptions>
объект. Вы можете сделать это черезMicrosoft.Extensions.Options.Options
вспомогательный класс. Например:Вы можете немного упростить это, чтобы:
Очевидно, что это не очень полезно как есть. Вам нужно будет создать и заполнить объект SampleOptions и передать его в метод Create.
источник
new OptionsWrapper<SampleOptions>(new SampleOptions());
везде писатьЕсли вы намереваетесь использовать Mocking Framework, как указано @TSeng в комментарии, вам необходимо добавить следующую зависимость в свой файл project.json.
После восстановления зависимости использовать структуру MOQ так же просто, как создать экземпляр класса SampleOptions и затем, как уже упоминалось, назначить его Value.
Вот схема кода, как это будет выглядеть.
После того, как макет настроен, вы можете передать макет объекта конструктору как
НТН.
К вашему сведению, у меня есть репозиторий git, в котором описаны эти 2 подхода на Github / patvin80
источник
Вы можете вообще избежать использования MOQ. Используйте в своих тестах файл конфигурации .json. Один файл для множества файлов тестовых классов. Будет хорошо использовать
ConfigurationBuilder
.Пример appsetting.json
Пример класса сопоставления настроек:
Пример услуги, которая нужна для тестирования:
Тестовый класс NUnit:
источник
Данный класс
Person
зависит отPersonSettings
следующего:IOptions<PersonSettings>
можно высмеять иPerson
протестировать следующим образом:Для того, чтобы впрыснуть
IOptions<PersonSettings>
вPerson
вместо того , чтобы передать его в явном виде в CTOR, используйте этот код:источник
Вы всегда можете создать свои параметры с помощью Options.Create (), а затем просто использовать AutoMocker.Use (options) перед фактическим созданием фиктивного экземпляра репозитория, который вы тестируете. Использование AutoMocker.CreateInstance <> () упрощает создание экземпляров без ручной передачи параметров
Я немного изменил ваш SampleRepo, чтобы иметь возможность воспроизвести поведение, которого, как мне кажется, вы хотите добиться.
источник
Вот еще один простой способ, который не требует использования Mock, но вместо этого использует OptionsWrapper:
источник
Для моих системных и интеграционных тестов я предпочитаю иметь копию / ссылку на мой файл конфигурации внутри тестового проекта. Затем я использую ConfigurationBuilder, чтобы получить параметры.
Таким образом, я могу использовать конфигурацию везде внутри моего TestProject. Для модульных тестов я предпочитаю использовать MOQ, как описано в patvin80.
источник
Согласитесь с Алехой, что, наверное, лучше использовать конфигурационный файл testSettings.json. А затем вместо того, чтобы вводить IOption, вы можете просто вставить реальные SampleOptions в свой конструктор класса, при модульном тестировании класса вы можете сделать следующее в фикстуре или снова просто в конструкторе тестового класса:
источник