首页 文章

将测试项目appSettings附加到ASP.NET Core集成测试

提问于
浏览
0

我正在these docs之后创建ASP.NET核心集成测试(基于xUnit) . 我想用自己的 appsettings.json 启动测试Web服务器 . 我的缩写文件夹结构是:

\SampleAspNetWithEfCore
\SampleAspNetWithEfCore\SampleAspNetWithEfCore.csproj
\SampleAspNetWithEfCore\Startup.cs
\SampleAspNetWithEfCore\appsettings.json
\SampleAspNetWithEfCore\Controllers\*

\SampleAspNetWithEfCore.Tests\SampleAspNetWithEfCore.Tests.csproj
\SampleAspNetWithEfCore.Tests\IntegrationTests.cs
\SampleAspNetWithEfCore.Tests\appsettings.json

然后我有这些实用程序:

public static class ServicesExtensions
{
    public static T AddOptions<T>(this IServiceCollection services, IConfigurationSection section)
        where T : class, new()
    {
        services.Configure<T>(section);
        services.AddSingleton(provider => provider.GetRequiredService<IOptions<T>>().Value);

        return section.Get<T>();
    }
}

Startup.cs ConfigureServices(...) 里面我这样做:

services.AddOptions<SystemOptions>(Configuration.GetSection("System"));

像这样反复到 appsettings.json 部分:

"System": {
  "PingMessageSuffix": " suffix-from-actual-project"
}

So far so good: this is picked up in a strongly typed manner. 我的控制器获取一个镜像json结构的 SystemOptions 实例,控制器正确使用后缀 .

The problems are with building the Integration Tests WebHost . 我希望从我的真实项目中运行 Startup ,具有自己的 appsettings.json 设置,但作为额外的设置层,我希望添加来自我的测试csproj的 appsettings.json ,覆盖任何设置(如果适用) . 这是我从测试项目中获得的应用程序:

"System": {
  "PingMessageSuffix": " suffix-from-test-appsettings"
}

这是我尝试过的:

public class CustomWebApplicationFactory : WebApplicationFactory<Startup>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder
            .UseStartup<Startup>()
            .ConfigureAppConfiguration(config => config
                .AddJsonFile("appsettings.json")
            );
    }
}

但是,这不起作用 . 如果我在控制器中遇到断点,我只看到基础项目中的设置 . 控制器只是回显当前的配置值,逻辑上返回的结果也不是预期的 .

The documentation未在页面的任何位置提及"appsettings" .

Bottom line :在运行ASP.NET核心集成测试时,如何从测试项目的appsettings.json文件中添加一层appSettings?

2 回答

  • 1

    解决它像这样:

    • 对于测试项目中的 appsettings.json ,设置属性:

    • Build ActionContent

    • Copy to Output DirectoryCopy if newer

    • 使用自定义 WebApplicationFactory 如下:

    public class CustomWebApplicationFactory : WebApplicationFactory<Startup>
    {
        protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            var configuration = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .Build();
    
            // Note:         ↓↓↓↓
            builder.ConfigureTestServices(services => 
                services.AddOptions<SystemOptions>(configuration.GetSection("System"))
            );
        }
    }
    

    瞧:它有效!

    需要的第一步是让 ConfigurationBuilder 轻松找到您的json文件 . 第二步巧妙地使用 ...TestServices 配置(如果使用常规 ConfigureServices 方法,它将在启动的服务配置之前被调用并被覆盖) .

    Footnote :评论者(在这个问题上)已经提到在SUT项目中拥有一个 appsettings.ci.json 文件可能会更好,并且可以通过环境(通过启动设置或通过WebHostBuilder设置)控制环境 . 该文档链接到一些关闭的GitHub问题,这些问题提出了相同的建议:871290607153 . 根据您的情况和品味,这可能是更好或更惯用的解决方案 .

  • 1

    单元测试项目和集成测试项目都需要自己的应用程序 . 我们称之为appsettings.Test.json

    然后我们使用Microsoft.Extensions.Configuration来访问它们 . 所以通常在测试中我会做类似的事情:

    private readonly IConfiguration _configuration;
    
        public HomeControllerTests()
        {
              _configuration = new ConfigurationBuilder()
               .AddJsonFile("appsettings.Test.json")
               .Build();
        }
    

    然后通过以下方式引用此文件中的值:

    _configuration["user:emailAddress"]
    

    文件的位置如下:

    "user": { "emailAddress": "myemail.com", …...
    

    对于您要执行的操作,您可能需要创建一个类似于我的appsettings.test.json文件,该文件位于主apsettings文件旁边 . 然后,您将要测试环境,然后添加appropritate appsettings文件 .

相关问题