由于 HttpStatusCode.TemporaryRedirect 导致 VSTS 管道中的 ASP.NET Core 单元测试失败

Posted

技术标签:

【中文标题】由于 HttpStatusCode.TemporaryRedirect 导致 VSTS 管道中的 ASP.NET Core 单元测试失败【英文标题】:Unit tests for ASP.NET Core failing in VSTS pipeline due to HttpStatusCode.TemporaryRedirect 【发布时间】:2020-07-18 19:14:57 【问题描述】:

我有一个使用 xUnitFluentAssertions 框架的 ASP.NET Core 2.2 WebAPI。它创建一个Microsoft.AspNetCore.TestHost.TestServer,并从该服务器对象中使用Microsoft.AspNetCore.TestHost.TestServer.CreateClient() API 创建一个HttpClient

单元测试在我使用 Visual Studio 2017 Pro 的本地 Windows 10 机器上运行良好。我提交了代码,然后做了一个拉取请求。拉取请求会自动启动构建过程以确保其构建。构建完成后,它会查找然后运行单元测试。在这一点上它失败了。我有 242 个单元测试。所有 242 单元测试都失败,代理报告的错误完全相同:

Expected resp.StatusCode to be OK, but found TemporaryRedirect.

所有 242 个单元测试都向测试服务器发出请求,因此它们都期望得到HttpStatusCode.OK(或类似的期望)响应。我不应该期待HttpStatuscode.TemporaryRedirect,所以我真的不想为此添加测试用例。

构建服务器在 VSTS 中作为安装了 Visual Studio 2017 Pro 的 Microsoft Server 2012 R2 运行。

为什么TestServer 对象会返回重定向?

如果没有办法解决这个问题,我可以强制HttpClient 在收到此状态时自动重定向,以便我只获得 API 调用的结果吗?

这是我用来创建服务器和客户端的代码:

var config = new ConfigurationBuilder()
    .SetBasePath(Path.GetFullPath("../../../../XXXXXXXXService/"))
    .AddJsonFile("appsettings.json", optional: false)
    .Build();

_server = new TestServer(new WebHostBuilder().UseStartup<Startup>().UseConfiguration(config));
TestHttpClient = _server.CreateClient();

一个失败的单元测试示例:

private string DeriveHttpPath(string path) =>
    $"/_rootPath.Trim('/')/path.TrimStart('/')";

private static async Task<TResult> ValidateAndReadResponseAsync<TResult>(
    HttpResponseMessage resp, HttpStatusCode statusShouldBe, Func<TResult> defFactory = null)

    (resp.IsSuccessStatusCode ? HttpStatusCode.OK : resp.StatusCode).Should().Be(statusShouldBe);
    try
    
        return await resp.Content.ReadAsAsync<TResult>();
    
    catch (Exception ex)
    
        return defFactory != null ? defFactory.Invoke() : throw ex;
    


public async Task<TResult> GetDocumentDataAsync<TResult>(string documentId,
    string path = null, HttpStatusCode statusShouldBe = HttpStatusCode.OK)

    using (var msg = new HttpRequestMessage(HttpMethod.Get,
        DeriveHttpPath($"_collectionId/documentId?path=path")))
    using (var resp = await _httpClient.SendAsync(msg))
    
        return await ValidateAndReadResponseAsync<TResult>(resp, statusShouldBe);
    

_rootPath 将是控制器的根,即:/api/MyController

感谢您的帮助。

【问题讨论】:

您能否向我们展示您失败的 integration 测试之一和您的 startup.cs? 添加了一个代码示例。 startup.cs 文件很大,因为它在单元测试项目和主 API 之间共享。我没有做任何中间件或任何会摆弄 http 请求管道的东西。只是注入一些临时服务。 我添加了一些调试代码——它试图做的是从 HTTP 重定向到 HTTPS。所以我会假设这是我的 startup.cs 中的一些代码强制 HTTPS 重定向。但为什么它在本地工作得很好? TestServer 是否处理 HTTPS 请求? 【参考方案1】:

我遇到的问题是因为这是在 startup.cs: 中定义的:

#if !DEBUG
    app.UseHttpsRedirection();
#endif

所以当我在本地运行单元测试时,它被编译为Debug,当它被推送到构建服务器时,它被编译为Release,并且打开了Https-Redirection。

我取出该代码并通过在 Azure 中设置我的 WebAPI HTTPS-Only。

【讨论】:

感谢您在这里分享您的解决方案,您能接受您的解决方案作为答案吗?因此,对于遇到相同问题的其他成员轻松找到解决方案将很有帮助。祝你有美好的一天:) @HughLin-MSFT :他们让你等待 24 小时才能接受你自己的答案,而我只是忘了回来。谢谢提醒:)

以上是关于由于 HttpStatusCode.TemporaryRedirect 导致 VSTS 管道中的 ASP.NET Core 单元测试失败的主要内容,如果未能解决你的问题,请参考以下文章

由于目标计算机积极拒绝,无法连接。

我在Android Studio工作,由于系统崩溃,一个或多个功能由于频繁的系统崩溃而崩溃。我应该如何恢复它?

SQL Server 服务由于登录失败而无法启动怎么办

Fiddler由于目标计算机积极拒绝,无法连接的解决方法

为啥我收到“由于保护级别而无法访问”错误?

SVN 由于目标机器积极拒绝,无法连接