Asp.net-Mvc

在 .NET Core 中使用 IOptions<> 進行集成測試

  • February 1, 2017

我傳給IOption&lt;T&gt;我的CommandBus,所以我可以從我的ServiceBusSetting班級獲取設置。我想對我的匯流排進行集成測試。我不想解決它只是使用new QueueCommandBus並需要傳遞IOptions給它。

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

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

這工作正常,但感覺非常複雜的程式碼IOptions&lt;T&gt;從我appsetting.json的測試項目中獲取。

如果這是唯一的方法還是有更好的方法,有什麼線索嗎?

您不需要創建ServiceCollectionor IServiceProvider。該IConfiguration介面有一個Bind()方法,或者從 .NET Core 1.1 開始,Get&lt;T&gt;您可以使用它直接獲取強類型對象:

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

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

// .NET Core 1.1
var options = config.Get&lt;ServiceBusAppSettings&gt;();

我喜歡將這些作為靜態方法添加到我的AppSettings強類型對像中,以方便在我的 Web 應用程序和單元測試中從 JSON 載入它們。

應用設置.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&lt;AppSettings&gt;();
       }
   }
}

**ASP.NET Core 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&lt;AppSettings&gt;(Configuration);

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

       // Add framework services.
       services.AddMvc()
           .AddJsonOptions(options =&gt;
           {
               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&lt;MyDbContext&gt;(opt =&gt; opt.UseMySql(conn));
   }
}

在測試類:

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

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

引用自:https://stackoverflow.com/questions/35649045