【问题标题】:How to use AddInMemoryCollection in a .NET 6 integration test?如何在 .NET 6 集成测试中使用 AddInMemoryCollection?
【发布时间】:2021-10-03 12:07:22
【问题描述】:

documentation about how to develop integration tests for .NET 6 。从逻辑上讲,我想通过更改配置参数来模拟外部依赖项(通常是 url 引用一些外部系统而不是 WireMock server)。这可以通过名为 AddInMemoryCollection 的方法来完成。我在为 .NET 5 开发集成测试时一直在使用它。但是对于 .NET 6 应用程序(通常是没有 Startup 类的应用程序)我没有成功。

问题是我需要找到一种方法来调用CreateClient,然后确保在调用Program.cs 代码之前调用AddInMemoryCollection,以便在使用它们之前修改配置参数。我该怎么做呢?如何在 .NET 6 集成测试中正确使用 AddInMemoryCollection?

这是一个不起作用的例子。 AddInmemoryCollection 不会修改 appsettings 值。使用 .NET 5 这样的代码可以工作(但我只是参考启动)。

    [Fact]
    public void ActualTest()
    {
        TryAddInMemoryCollection("http://localhost:1234");
    }

    private void TryAddInMemoryCollection(string urlOnLocalhost)
    {
        var factory = new IntegrationWebApplicationFactory<Program>();
        factory.WithWebHostBuilder(whb =>
        {
            whb.ConfigureAppConfiguration((context, configbuilder) =>
            {
                configbuilder.AddInMemoryCollection(new Dictionary<string, string>()
                 {
                     { "Google",urlOnLocalhost }
                 });
            });
        }).CreateClient();
    }

在我的 Program.cs 中

var googleLocation = builder.Configuration["Google"];
Console.WriteLine($"GOOGLELOCATION!! {googleLocation}");

【问题讨论】:

  • 你试过什么?什么不工作?请发帖a minimal reproducible example
  • @MarkSeemann 我已经尝试让 .NET 5 在调用 AddInMemoryCollection 后触发 Startup 类。我在 .NET 5 上取得了成功。但为此,发布它是没有意义的。在典型的 .NET 6 应用程序中,没有启动。我不知道在 .NET 6 集成测试中在哪里调用 AddInMemoryCollection,所以我不能发布一个最小的可重现示例。
  • @Daan 在问题本身而不是 cmets 中发布代码。您的真实问题是从哪里获得Configuration 的吗?你试过builder.Configuratiion吗?如果您进行集成测试,您要修改谁的配置?考试的? WebApplicationFactory 的?
  • @Daan 上次你问到 WebApplicationFactory 是一个很好的机会来纠缠 Damien Edwards 和 ASP.NET Core 团队的其他成员来改进文档。不过这次还不清楚你问的是什么。文档显示how to override the Startup settings 以及如何使用customize individual clients。你在问什么?
  • @PanagiotisKanavos 感谢您的反馈。您引用的链接刚刚证明了我的问题:AddInMemoryCollection 用法未描述。我只想覆盖 web 应用程序的 appsettings 中的一个值。就这样。这在 .NET Core 3.1、2.1 和 .NET 5 中运行良好。在 .NET 6 中则不行。附上代码。

标签: asp.net-core integration-testing tdd .net-6.0


【解决方案1】:

你可以这样做:

[Fact]
public void ActualTest()
{
    TryAddInMemoryCollection("http://localhost:1234");
}

private void TryAddInMemoryCollection(string urlOnLocalhost)
{
    var factory = new IntegrationWebApplicationFactory<Program>();
    factory.WithWebHostBuilder(whb =>
    {
       whb.UseSetting("Google",urlOnLocalhost);
    }).CreateClient();
}

您还可以添加一个接受字典的扩展方法:

public static IWebHostBuilder UseSetting(this IWebHostBuilder builder, IDictionary<string, string> settings)
{
    foreach (var (key, value) in settings)
    {
        builder.UseSetting(key, value);
    }
    return builder;
}

【讨论】:

    【解决方案2】:

    https://github.com/dotnet/aspnetcore/issues/37680

    截至目前,这在 .net 6 中是不可能的。如果你坚持使用最少的 api / no startup.cs,你需要小心地懒惰地注册每个服务,而不是实例化任何依赖于配置的东西。您的测试配置只会在您的实体 Program.cs 执行后添加。

    没有什么能阻止您在 .net 6 中使用 Startup.cs。那么这根本不是问题。可能会或可能不会在 .net 7 中得到修复。我们还不知道。

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 2023-01-23
      • 2022-12-20
      • 1970-01-01
      • 2022-06-16
      • 2013-12-14
      • 1970-01-01
      • 2019-12-17
      • 1970-01-01
      相关资源
      最近更新 更多