在集成测试中设置环境

mic*_*cer 6 c# testing .net-core asp.net-core

我想在我的集成测试中使用WebApplicationFactory. 默认情况下, env 设置为Development. 我的 Web 应用程序工厂的代码如下所示:

public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<TStartup>
    where TStartup : class
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.UseSolutionRelativeContentRoot(AppContext.BaseDirectory);

        base.ConfigureWebHost(builder);
    }

    protected override IWebHostBuilder CreateWebHostBuilder()
    {
        return WebHost.CreateDefaultBuilder()
            .UseStartup<TStartup>()
            .UseEnvironment("test"); // i want to launch `test` environment while im
                                     // testing my app
    }
}
Run Code Online (Sandbox Code Playgroud)

当我开始调试Startup类时(当我运行测试时)我仍然得到Development环境:

public Startup(IHostEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", false, true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true)
        // env.EnvironmentName is set to 'Development' while i set it to 'test'
        // in my WebApplicationFactory
        .AddEnvironmentVariables();

    Configuration = builder.Build();
}
Run Code Online (Sandbox Code Playgroud)

如何WebApplicationFactory正确设置环境?或者也许如何仅在启动时更改测试策略我依赖于appsettings文件?

小智 35

我遇到了同样的问题,并为我解决了以下问题:

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
     builder.UseEnvironment("Test");
}
Run Code Online (Sandbox Code Playgroud)


Ros*_*sco 11

作为替代方案,如果您不使用 custom WebApplicationFactory,则可以使用扩展方法指定环境WithWebHostBuilder

var application = new WebApplicationFactory<Startup>()
    .WithWebHostBuilder(builder =>
    {
        builder.UseEnvironment("Test");
    });
Run Code Online (Sandbox Code Playgroud)

在.Net 6.0 中测试


Ash*_*h K 11

使用.NET 6 MVC项目的完整源代码:

https://github.com/akhanalcs/mvc-integration-test


步骤 1: 创建一个在您的测试项目中命名的类CustomWebApplicationFactory

public class CustomWebApplicationFactory<TProgram>
    : WebApplicationFactory<TProgram> where TProgram : class
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        // Works for: Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") in Program.cs
        Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "test");
        
        // OR

        // Works for: builder.Environment.EnvironmentName in Program.cs
        builder.UseEnvironment("test"); 
    }
}
Run Code Online (Sandbox Code Playgroud)

第 2 步: 创建SomeServiceTests.cs文件并从那里使用它。(我这里使用的是MSTest)

using Microsoft.AspNetCore.Mvc.Testing;

namespace SomeProject.IntegrationTests.SomeServiceTests;

[TestClass]
public class SomeServiceTests
{
    private static WebApplicationFactory<Program> _factory;

    [ClassInitialize]
    public static void ClassInit(TestContext testContext)
    {
        Console.WriteLine(testContext.TestName);
        _factory = new CustomWebApplicationFactory<Program>();
    }

    [ClassCleanup]
    public static void ClassCleanup()
    {
        _factory.Dispose();
    }

    [TestMethod]
    public async Task Some_Test_Method_Here_Async()
    {
        // ARRANGE
        var client = _factory.CreateClient();

        // If I wanted to resolve some service:
        //using var scope = _factory.Services.CreateScope();
        //var scopedServices = scope.ServiceProvider;
        //var db = scopedServices.GetRequiredService<ApplicationDbContext>();

        // ACT

        // ASSERT
    }
}
Run Code Online (Sandbox Code Playgroud)

第3步:Program.cs像这样使用环境变量:

var builder = WebApplication.CreateBuilder(args);

var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? builder.Environment.EnvironmentName;

builder.Configuration
       .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
       .AddJsonFile($"appsettings.{environmentName}.json", optional: true, reloadOnChange: true);

// Rest of the code here
Run Code Online (Sandbox Code Playgroud)