亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

單元測試ASP.NET Core HttpResponse.OnStarting()

單元測試ASP.NET Core HttpResponse.OnStarting()

C#
手掌心 2021-03-30 09:39:00
我有一個ASP.NET Core中間件,負責將標頭添加到響應中。按照以下最佳實踐,我將在的上下文中執行標頭更改HttpResponse.OnStarting(Func<Task>),以確保在將響應刷新到客戶端之前立即執行回調。public class ResponseHeadersMiddleware{    private readonly RequestDelegate _next;    public ResponseHeadersMiddleware(RequestDelegate next)    {        _next = next;    }    public async Task Invoke(HttpContext context)    {        context.Response.OnStarting(() =>        {            context.Response.Headers.Add("X-Some-Header", "Foobar");            return Task.CompletedTask;        });        // Pass the request through the pipeline         await _next(context);    }}這可以按預期工作,但是我不確定為這種實際觸發的中間件編寫單元測試的最佳方式HttpResponse.OnStarting()。我唯一能想到的就是使用aMicrosoft.AspNetCore.TestHost構建TestServer集成中間件并執行完整請求管道的a。盡管功能正常,但它更像是一個集成測試,而不是真正的單元測試。[Fact]public async Task when_adding_response_headers(){    // ARRANGE    var subject = new TestServer(new WebHostBuilder()        .UseStartup<TestStartup<ResponseHeadersMiddleware>>());    // ACT    var response = await subject.CreateClient()        .SendAsync(new HttpRequestMessage(HttpMethod.Get, "/")); // middleware fires for all requests    // ASSERT    Assert.True(response.Headers.TryGetValues("X-Some-Header", out var someHeader));    Assert.Equals("Foobar", someHeader.FirstOrDefault()}private class TestStartup<TMiddleware> where TMiddleware : class{    public void ConfigureServices(IServiceCollection services)    {        RequestDelegate requestDelegate = context => Task.FromResult(0);        services.AddSingleton(requestDelegate);        services.AddSingleton<TMiddleware>();    }    public void Configure(IApplicationBuilder app)    {        dynamic middleware = app.ApplicationServices.GetService(typeof(TMiddleware));        app.Use(async (ctx, next) =>        {            await middleware.Invoke(ctx);            await next();        });    }}有沒有一種方法可以HttpResponse.OnStarting()在沒有進行端到端集成測試的情況下觸發傳遞給我的中間件的HttpContext?
查看完整描述

2 回答

?
慕蓋茨4494581

TA貢獻1850條經驗 獲得超11個贊

在倉庫中進行一些挖掘并查看了他們的一些測試之后,我想到了這個想法,以利用受控上下文的響應功能。


這意味著需要找到一種方法來捕獲傳遞給的回調OnStarting。決定嘗試通過虛擬響應功能來獲取它。


private class DummyResponseFeature : IHttpResponseFeature {

    public Stream Body { get; set; }


    public bool HasStarted { get { return hasStarted; } }


    public IHeaderDictionary Headers { get; set; } = new HeaderDictionary();


    public string ReasonPhrase { get; set; }


    public int StatusCode { get; set; }


    public void OnCompleted(Func<object, Task> callback, object state) {

        //...No-op

    }


    public void OnStarting(Func<object, Task> callback, object state) {

        this.callback = callback;

        this.state = state;

    }

    

    bool hasStarted = false;

    Func<object, Task> callback;

    object state;

    

    public Task InvokeCallBack() {

        hasStarted = true;

        return callback(state);

    }

}

在測試中,我將在上設置功能HttpContext,然后直接測試中間件。


[Fact]

public async Task when_adding_response_headers() {

    // ARRANGE

    var feature = new DummyResponseFeature();

    var context = new DefaultHttpContext();

    context.Features.Set<IHttpResponseFeature>(feature);

    

    RequestDelegate next = async (ctx) => {

        await feature.InvokeCallBack();

    };

    

    var subject = new ResponseHeadersMiddleware(next);


    // ACT

    await subject.Invoke(context);


    // ASSERT

    var response = context.Response;

    Assert.True(response.Headers.TryGetValues("X-Some-Header", out var someHeader));

    Assert.Equals("Foobar", someHeader.FirstOrDefault()

}

在中間件中等待請求委托時,讓請求委托調用來捕獲該回調


查看完整回答
反對 回復 2021-04-10
  • 2 回答
  • 0 關注
  • 375 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號