在单位测试情况下检查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));
}

为了让您对我采用的中间件方法有更多的了解,我正在采用此答案中找到的方法。

应用程序运行时正常管道正常。但是,使用测试中的DefaulthttpContext方法,响应主体总是回到空的,并且contentLength为null。因此,测试中的我的streamText变量是一个空字符串。

在这种情况下,是否可以检查中间件对上下文写的内容?这是适当的方法,还是有更好的方法。

考虑自己设置身体,以便您控制流

@andrewstanton-nurse提供的评论

DefaultHttpContext中的Response.Body流是Stream.Null,它是忽略所有读/写入的流。您需要在调用方法之前自己设置流。

进一步 - 现在将允许设置身体,但是要正确读取它,我们必须按照此答案将指针设置为开始,然后再使用StreamReader。

//...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

相关内容

  • 没有找到相关文章

最新更新