1

我已经设置了一个集成测试:

public class IntegrationTests
{
    private readonly TestServer _server;
    private readonly HttpClient _client;

    public IntegrationTests()
    {
        _server = new TestServer(WebHost.CreateDefaultBuilder().UseEnvironment("Development").UseStartup<Startup>())
        {
            PreserveExecutionContext = true,
        };
        _client = _server.CreateClient();
    }

    [Test]
    public async Task RunARoute()
    {
        var response = await _client.GetAsync("/foo");

        Check.That(response.IsSuccessStatusCode).IsTrue();
    }
}

启动:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews()
        .AddApplicationPart(typeof(HomeController).Assembly)
        .AddControllersAsServices()
        .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

    services
        .ConfigureAll(Configuration) // Add the configuration sections
        .AddAllServices() // DI
        // Other:
        .AddAutoMapperProfiles(AutoMapperConfiguration.LoadConfig)
        .AddCacheHelper(e => {})
        .AddSession(opt => opt.Cookie.IsEssential = true);
}

public void Configure(IApplicationBuilder app)
{
    app.UseHttpsRedirection()
        .UseStaticFiles()
        .UseRouting()
        .UseCookiePolicy()
        .UseSession()
        .UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                "default",
                "{controller=Home}/{action=Index}/{id?}");
        });
}

在测试方法中,我调用的路由重定向到另一个路由:return RedirectToAction(nameof(Bar)). 我想测试该Bar方法是否正确返回了页面,但不幸的是,该页面HttpClient没有重定向调用:我的测试失败并显示代码302

我在 Internet 上读到,当尝试从 HTTPS 路由重定向到 HTTP 路由时,通常会发生此问题,但是 AFAIK,这里不是这种情况,因为测试服务器使用基本 URL 创建客户端http://localhost/,并且重定向 URL 是相对的(因此没有指定协议)。

如何确保客户端重定向呼叫?

4

1 回答 1

2

这是设计使然。如果你检查TestServer源代码

public HttpMessageHandler CreateHandler()
{
    var pathBase = BaseAddress == null ? PathString.Empty : PathString.FromUriComponent(BaseAddress);
    return new ClientHandler(pathBase, Application) { AllowSynchronousIO = AllowSynchronousIO, PreserveExecutionContext = PreserveExecutionContext };
}

public HttpClient CreateClient()
{
    return new HttpClient(CreateHandler()) { BaseAddress = BaseAddress };
}

您会看到它没有启用自动重定向功能,这实际上是HttpClientHandler默认情况下通常使用的一部分HttpClient

TestServer但是,使用自定义处理程序,在创建HttpClient. 您需要访问处理程序,因为测试服务器在内部创建客户端,所以您无法访问。

因此,所描述的代码的行为符合预期。

HTTP 响应状态码 302 Found 是执行重定向的常用方法。

检查响应标头以断言重定向位置标头指向所需的 URL,以断言预期的行为。

也可以考虑手动调用重定向的 URL 来验证是否会返回 HTTP 响应状态码 200 OK

[Test]
public async Task RunARoute_Should_Redirect() {        
    _server.PreserveExecutionContext = true;
    var client = _server.CreateClient();
    var response = await _client.GetAsync("/foo");

    Check.That(response.StatusCode).IsEqualTo(HttpStatusCode.Found); //302 Found

    var redirectUrl = response.Headers.Location;

    //assert expected redirect URL
    //...

    response = await _client.GetAsync(redirectUrl);       

    Check.That(response.IsSuccessStatusCode).IsTrue(); //200 OK
}
于 2020-02-12T14:47:27.593 回答