Integration test with IOptions<> in .NET Core

前端 未结 1 1052
北海茫月
北海茫月 2020-12-15 09:47

I pass IOption to my CommandBus so I can get the settings from my ServiceBusSetting class. I want to do an integration test o

相关标签:
1条回答
  • 2020-12-15 10:30

    You don't need to create the ServiceCollection or IServiceProvider. The IConfiguration interface has a Bind() method, or from .NET Core 1.1 onwards, Get<T> which you can use to get the strongly-typed object directly:

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

    I like to add these as static methods to my AppSettings strongly-typed object, to make it convenient to load them from JSON in both my web app and from unit tests.

    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 Core Startup.cs: (Getting the strongly-typed settings object is often helpful at this stage, when configuring the other services...)

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

    In Test Class:

    var testDir = AppContext.BaseDirectory;
    var settings = AppSettings.GetSettings(testDir, "Test");
    
    //Act
    var commandBus = new QueueCommandBus(settings);
    
    0 讨论(0)
提交回复
热议问题