Net Core集成测试:从其他程序运行Startup.cs和配置

时间:2019-08-01 23:20:27

标签: c# asp.net-core .net-core xunit .net-core-2.2

我们正在创建一个集成单元测试(Xunit),它称为Real Application Startup.cs。

由于某些原因,Real项目可以正确读取配置文件/属性,但是从集成测试中运行它时,它无法读取它。它不会在下面的Configuration(conf)变量中放置任何内容。我该如何解决? 原因是它没有启动是因为它没有读取来自读取配置文件的Net Core 2.2中新的内部依赖项注入。立即尝试使用.CreateDefaultBuilder。

IntegrationTest1.cs

        TestServer _server = new TestServer(new WebHostBuilder() .UseContentRoot("C:\\RealProject\\RealProject.WebAPI")
            .UseEnvironment("Development")
            .UseConfiguration(new ConfigurationBuilder()
            .SetBasePath("C:\\RealProject\\RealProject.WebAPI")
                .AddJsonFile("appsettings.json")
                .Build())
                .UseStartup<Startup>()
            .UseStartup<Startup>());

Real Project Startup.cs

    public Startup(IConfiguration configuration, IHostingEnvironment hostingEnvironment)
    {
        Configuration = configuration;
        HostingEnvironment = hostingEnvironment;
    }

    public IHostingEnvironment HostingEnvironment { get; }
    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public IServiceProvider ConfigureServices(IServiceCollection services)
    {

        var conf = Configuration;
        IConfiguration appConf = conf.GetSection("ConnectionStrings");
        var connstring = appConf.GetValue<string>("DatabaseConnection");

        services.AddDbContext<DbContext>(a => a.UseSqlServer(connstring));

Appsettings.Json

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ConnectionStrings": {
    "DatabaseConnection": "Data Source=.;Initial Catalog=ApplicationDatabase;Integrated Security=True"
  }
}

1 个答案:

答案 0 :(得分:-1)

您要做的是为WebApplication创建一个采用Startup类型的Factory。然后,您可以使用IClassFixture界面与测试类中的所有测试共享该工厂的上下文。

这在实践中是这样的:

public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<Startup> where TStartup : class
{
    public CustomWebApplicationFactory() { }

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder
            .ConfigureTestServices(
                services =>
                {
                    services.Configure(AzureADDefaults.OpenIdScheme, (System.Action<OpenIdConnectOptions>)(o =>
                    {
                        // CookieContainer doesn't allow cookies from other paths
                        o.CorrelationCookie.Path = "/";
                        o.NonceCookie.Path = "/";
                    }));
                }
            )
            .UseEnvironment("Production")
            .UseStartup<Startup>();
    }
}


public class AuthenticationTests : IClassFixture<CustomWebApplicationFactory<Startup>>
{
    private HttpClient _httpClient { get; }

    public AuthenticationTests(CustomWebApplicationFactory<Startup> fixture)
    {
        WebApplicationFactoryClientOptions webAppFactoryClientOptions = new WebApplicationFactoryClientOptions
        {
            // Disallow redirect so that we can check the following: Status code is redirect and redirect url is login url
            // As per https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2#test-a-secure-endpoint
            AllowAutoRedirect = false
        };

        _httpClient = fixture.CreateClient(webAppFactoryClientOptions);
    }

    [Theory]
    [InlineData("/")]
    [InlineData("/Index")]
    [InlineData("/Error")]
    public async Task Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(string url)
    {
        // Act
        HttpResponseMessage response = await _httpClient.GetAsync(url);

        // Assert
        response.EnsureSuccessStatusCode();
    }
}

我按照指南here使用自己的代码来完成此工作。

相关问题