2017-08-30 28 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。 –

相关问题