2016-02-26 3 views
6

Я передаю IOption<T> в мой CommandBus, поэтому я могу получить настройки из своего класса ServiceBusSetting. Я хочу выполнить интеграционный тест моего автобуса. Я не хочу его разрешать, просто используйте new QueueCommandBus и ему нужно передать IOptions.Интеграционный тест с IOptions <> в .NET Core

var services = new ServiceCollection().AddOptions(); 
     services.Configure<ServiceBusAppSettings>(Configuration.GetSection("ServiceBus")); 
     var options = services.BuildServiceProvider().GetService<IOptions<ServiceBusAppSettings>>(); 

     ////Act 
     var commandBus = new QueueCommandBus(options); 

Это прекрасно работает, но чувствует себя очень сложный код, чтобы получить IOptions<T> от моего appsetting.json в моем тестовом проекте.

Любая подсказка, если это единственный способ или есть лучший способ?

ответ

3

Вам не нужно создавать ServiceCollection или IServiceProvider. Интерфейс IConfiguration имеет метод Bind(), или .NET Ядра 1,1 года, Get<T>, которые вы можете использовать, чтобы получить строго типизированный объект непосредственно:

var config = Configuration.GetSection("ServiceBus"); 

// .NET Core 1.0 
var options = new ServiceBusAppSettings(); 
config.Bind(options); 

// .NET Core 1.1 
var options = config.Get<ServiceBusAppSettings>(); 

мне нравится, чтобы добавить их как статические методы в мой AppSettings сильновзаимодействующих набранный объект, чтобы было удобно загружать их из JSON как в моем веб-приложении, так и из модульных тестов.

AppSettings.cs:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks; 
using Microsoft.Extensions.Configuration; 

namespace My.Namespace 
{ 
    public class AppSettings 
    { 
     public class ServiceBusAppSettings 
     { 
      public string Setting1; 
      public int Setting2; 
     } 

     public class ApiSettings 
     { 
      public bool FormatJson { get; set; } 
     } 

     public class MySqlSettings 
     { 
      public string User { get; set; } 
      public string Password { get; set; } 
      public string Host { get; set; } 
      public string Database { get; set; } 
      public int Port { get; set; } = 3306; 

      public string GetConnectionString() 
      { 
       return $"Server={Host};Database={Database};Port={Port};Uid={User};Pwd={Password}"; 
      } 

     } 

     public ServiceBusAppSettings ServiceBus { get; set; } = new ServiceBusAppSettings(); 
     public ApiSettings Api { get; set; } = new ApiSettings(); 
     public MySqlSettings MySql { get; set; } = new MySqlSettings(); 

     // Static load helper methods. These could also be moved to a factory class. 
     public static IConfigurationRoot GetConfiguration(string dir) 
     { 
      return GetConfiguration(dir, null); 
     } 

     public static IConfigurationRoot GetConfiguration(string dir, string environmentName) 
     { 
      if (string.IsNullOrEmpty(environmentName)) 
       environmentName = "Development"; 

      var builder = new ConfigurationBuilder() 
       .SetBasePath(dir) 
       .AddJsonFile("appsettings.json", true, true) 
       .AddJsonFile($"appsettings.{environmentName}.json", true) 
       .AddEnvironmentVariables(); 

      return builder.Build(); 
     } 

     public static AppSettings GetSettings(string dir) 
     { 
      return GetSettings(dir, null); 
     } 

     public static AppSettings GetSettings(string dir, string environmentName) 
     { 
      var config = GetConfiguration(dir, environmentName); 
      return GetSettings(config); 
     } 

     public static AppSettings GetSettings(IConfiguration config) 
     { 
      return config.Get<AppSettings>(); 
     } 
    } 
} 

ASP.NET Основные Startup.cs: (Получение сильно типизированных параметров объекта часто бывает полезно на данном этапе, при настройке других услуг ...)

public class Startup 
{ 
    public Startup(IHostingEnvironment env) 
    { 
     Configuration = AppSettings.GetConfiguration(env.ContentRootPath, env.EnvironmentName); 
    } 

    public IConfigurationRoot Configuration { get; } 

    // This method gets called by the runtime. Use this method to add services to the container. 
    public void ConfigureServices(IServiceCollection services) 
    { 
     // Configure the service collection. 
     services.AddOptions(); 
     services.Configure<AppSettings>(Configuration); 

     // It can also be handy to get the AppSettings object here. 
     var settings = AppSettings.GetSettings(Configuration); 

     // Add framework services. 
     services.AddMvc() 
      .AddJsonOptions(options => 
      { 
       options.SerializerSettings.ContractResolver = new DefaultContractResolver(); 
       // Pretty-print JSON in Development 
       options.SerializerSettings.Formatting = settings.Api.FormatJson ? Formatting.Indented : Formatting.None; 
      }); 

     // Store DB connection info in AppSettings too... 
     var conn = settings.MySql.GetConnectionString(); 
     services.AddDbContext<MyDbContext>(opt => opt.UseMySql(conn)); 
    } 
} 

В испытании класс:

var testDir = AppContext.BaseDirectory; 
var settings = AppSettings.GetSettings(testDir, "Test"); 

//Act 
var commandBus = new QueueCommandBus(settings); 
Смежные вопросы