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

时间:2020-04-06 17:44:18

标签: unit-testing asp.net-core azure-devops xunit windows-server-2012-r2

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

单元测试在使用V​​isual Studio 2017 Pro的本地Windows 10计算机上非常有效。我提交了代码,然后发出了请求请求。拉取请求会自动启动构建过程以确保构建成功。构建完成后,它将寻找并运行单元测试。在这一点上它失败了。我有242个单元测试。所有242单元测试均失败,并由代理报告完全相同的错误:

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

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

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

为什么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

谢谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我遇到的问题是因为这是在private void addCategoryChoice(Form form) { List<Category1> category1List = category1Impl.listProduct(); ChoiceRenderer renderer1=new ChoiceRenderer<Category1>() { @Override public Object getDisplayValue(Category1 value) { return value.getName(); } }; DropDownChoice<Category1> category1 = new DropDownChoice<Category1>("category1", new Model<Category1>(category1List.get(1)) , category1List,renderer1); category2List = category2Imple.listByCategory1Id(category1.getModelObject().getId()); ChoiceRenderer renderer2=new ChoiceRenderer<Category2>() { @Override public Object getDisplayValue(Category2 value) { return value.getName(); } }; DropDownChoice<Category2> category2 = new DropDownChoice("category2",category2List,renderer2); form.add(category2); category1.add(new AjaxEventBehavior("change") { @Override protected void onEvent(AjaxRequestTarget target) { category2List.clear(); int id=category1.getModelObject().getId(); category2List.addAll(category2Imple.listByCategory1Id(Integer.valueOf(id))); category2.setChoices(category2List); } }); form.add(category1); } 中定义的:

startup.cs

因此,当我在本地运行单元测试时,将其编译为Debug,在将其推送到构建服务器时,将其编译为Release,并打开Https-Redirection。

我通过在Azure中进行设置来取出该代码,并将WebAPI仅设置为HTTPS。