2017-08-30 27 views
5

我試圖用DefaultHttpContext對象來單元測試我的異常處理中間件。在單元測試情況下檢查DefaultHttpContext正文

我的測試方法是這樣的:

[Fact] 
public async Task Invoke_ProductionNonSuredException_ReturnsProductionRequestError() 
{ 
    var logger = new Mock<ILogger<ExceptionHandlerMiddleware>>(); 
    var middleWare = new ExceptionHandlerMiddleware(next: async (innerHttpContext) => 
    { 
     await Task.Run(() => 
     { 
      throw new Exception(); 
     }); 
    }, logger: logger.Object); 

    var mockEnv = new Mock<IHostingEnvironment>(); 
    mockEnv.Setup(u => u.EnvironmentName).Returns("Production"); 

    var context = new DefaultHttpContext(); 

    await middleWare.Invoke(context, mockEnv.Object); 

    var reader = new StreamReader(context.Response.Body); 
    var streamText = reader.ReadToEnd(); 

    //TODO: write assert that checks streamtext is the expected production return type and not the verbose development environment version. 
} 

在我的中間件,我寫這封信的背景是這樣的:

public static Task WriteResponse(HttpContext context, HttpStatusCode statusCode, object responseData, Formatting jsonFormatting) 
{ 
    context.Response.ContentType = "application/json"; 
    context.Response.StatusCode = (int)statusCode; 
    return context.Response.WriteAsync(JsonConvert.SerializeObject(responseData, jsonFormatting)); 
} 

爲了讓您更深入地瞭解中間件的方法,我已經採取,我正在採取在this answer here發現的方法。

工作正常,當應用程序運行它是正常的管道。但是,在測試中使用DefaultHttpContext方法時,響應正文始終爲空,並且ContentLength爲空。因此,我的streamText變量在測試中是一個空字符串。

在這種情況下,有可能檢查中間件寫入上下文的內容嗎?這是適當的方式,還是有更好的方法。

+0

在你的middleWare.Invoke()中會發生什麼?也許你只是不要在那裏調用WriteResponse()。 – Kostya

回答

4

考慮自己定身,讓你有

評論由@提供的數據流的控制AndrewStanton,護士

DefaultHttpContextResponse.Body流是Stream.Null,這是忽略所有讀取流/寫。在調用方法之前,您需要自己設置Stream。

此外 - 現在將允許設置主體,但爲了正確讀取它,我們必須在使用StreamReader之前將指針設置爲根據this answer開始。

//...code removed for brevity 

var context = new DefaultHttpContext(); 
context.Response.Body = new MemoryStream(); 

await middleWare.Invoke(context, mockEnv.Object); 


context.Response.Body.Seek(0, SeekOrigin.Begin); 
var reader = new StreamReader(context.Response.Body); 
var streamText = reader.ReadToEnd(); 

//...code removed for brevity 
+3

這是解決方案。 DefaultHttpContext中的Body流是Stream.Null,它是忽略所有讀/寫操作的流。在調用方法之前,您需要自己設置Stream。 –

相關問題