ASPNet.Core HostingEnvironment用于集成测试吗?

6
在为我的ASPNet.Core Web应用程序构建集成测试时,我遇到了一个问题。当我运行应用程序并读取配置时,其中包含了我apsettings.json文件中的所有信息。现在,当我按照下面所示运行集成测试时,启动程序被运行,但是配置不同。为什么会发生这种情况,我该如何确保它读取应用程序本身的配置?参考链接:https://learn.microsoft.com/en-us/aspnet/core/testing/integration-testing
[TestFixture]
class HSMControllerTests
{
    private readonly TestServer _server;
    private readonly HttpClient _client;

    public HSMControllerTests()
    {
        _server = new TestServer(new WebHostBuilder()
        .UseStartup<Startup>());
        _client = _server.CreateClient();
    }

    [Test]
    public async global::System.Threading.Tasks.Task GET_PingHSM_ShouldSucceedAsync()
    {
        HttpResponseMessage response = await _client.GetAsync("HSM/PingHSM");
        Assert.NotNull(response);
        Assert.IsInstanceOf<OkObjectResult>(response);
    }
}

我遇到了一个异常:缺少配置节ServiceConfig。

这是在我的应用程序中 Program.cs 中构建 WebHost 的方式:

WebHost.CreateDefaultBuilder(args)
       .UseStartup<Startup>()
       .UseKestrel(o => o.AddServerHeader = false)
       .Build();

可能是测试代码中构建方式的差异导致的问题吗?

修改后的ControllerTest构造函数:

public HSMControllerTests()
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(Path.GetFullPath(@"../../../../HSM.WebApi.IntegrationTests"))
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddEnvironmentVariables();

    Configuration = builder.Build();

    _server = new TestServer(WebHost.CreateDefaultBuilder()
        .UseStartup<Startup>());
    _client = _server.CreateClient();
}

现在,如何将新的配置注入到启动项中?我们的启动项定义如下:
public Startup(IConfiguration configuration, IHostingEnvironment environment)
        : base(typeof(Startup), configuration, environment)
{
}

根据 @poke 的上一篇帖子进行修改
_server = new TestServer(WebHost.CreateDefaultBuilder()
    .ConfigureAppConfiguration(configBuilder => new ConfigurationBuilder()
        .SetBasePath(Path.GetFullPath(@"../../../../HSM.WebApi.IntegrationTests"))
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddEnvironmentVariables()
    )
    .UseStartup<Startup>());

搞定了,有些问题还需要解决...

var config = new ConfigurationBuilder()
    .SetBasePath(Path.GetFullPath(@"../../../../HSM.WebApi.IntegrationTests"))
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
    .AddEnvironmentVariables();

var Configuration = config.Build();

_server = new TestServer(WebHost.CreateDefaultBuilder()
    .UseConfiguration(Configuration)
    .UseStartup<Startup>());
_client = _server.CreateClient();

但是现在,HostingEnvironment被设置为Tests应用程序的目录,而不是Web应用程序的目录,并且它试图从HomeController构造函数中的那里读取appsettings.json文件,位置如下:

public HSMController(IHostingEnvironment hostingEnvironment)
{
    _hostingEnvironment = hostingEnvironment;
    contentRootPath = _hostingEnvironment.ContentRootPath;
}

1
请发布完整的堆栈跟踪。“缺少配置部分ServiceConfig”并不是一个异常,我们也不知道它来自哪里。 - poke
1
"启动已经运行,但配置不同" - 不同的是什么?你是如何验证的? - poke
@vasiloreshenski,是的,现在可以了,但我宁愿使用Web应用程序中的那个。 - MB34
1
您可以使用 IWebHostBuilder.ConfigureAppConfiguration,例如 new WebHostBuilder().ConfigureAppConfiguration(configBuilder => configBuilder.SetBasePath(…).AddJsonFile(…)).UseStartup<Startup>()) - poke
看到修改,但启动时配置仍不正确,异常仍然发生。 - MB34
显示剩余6条评论
2个回答

7

ASP .Net Core 2.0

将appsettings.json文件复制到您的集成测试中,并将它们设置为始终复制。

创建MyTestServer类,因为它可能会在许多测试中被重用。请记住,CreateDefaultBuilder将自动加载您的appsettings并使用环境。

  public class ApiTestServer : TestServer
  {
    public ApiTestServer() : base(WebHostBuilder())
    { }

    private static IWebHostBuilder WebHostBuilder() =>
      WebHost.CreateDefaultBuilder()
        .UseStartup<Startup>()
        .UseEnvironment("Local")
        .UseKestrel(options =>
        {
          options.Listen(IPAddress.Any, 5001);
        });
  }

在你的测试中,

public SettingsTests()
{
  TestServer = new ApiTestServer();
  HttpClient = TestServer.CreateClient();
}

如何在不同的环境下运行相同的测试? 例如:“本地”和“开发”如果我使用这行代码 - “.UseEnvironment(“Local”)”,那么环境将始终是“Local”。您知道如何使用通用环境或以某种方式将其传递给代码吗? - Tim Amet

5

appsettings.json文件复制到集成测试项目文件夹中,并将其设置为“始终复制”,这样它就能正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接