本文介绍了在单元测试情况下检查 DefaultHttpContext 主体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 DefaultHttpContext 对象对我的异常处理中间件进行单元测试.

I'm trying to use the DefaultHttpContext object to unit test my exception handling middleware.

我的测试方法如下:

[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.
}

在我的中间件中,我正在写这样的上下文:

In my middleware, I am writing to the context like this:

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));
}

为了让您更深入地了解我采用的中间件方法,我采用了 这里的答案.

To give you more insight into the middleware approach I've taken, I'm taking the approach found in this answer here.

在应用程序运行时正常工作,它是正常的管道.但是,在测试中使用 DefaultHttpContext 方法时,响应正文总是返回空的,并且 ContentLength 为空.因此,我在测试中的 streamText 变量是一个空字符串.

Works fine when the app is running it's normal pipeline. However, using the DefaultHttpContext method in the test, the response body always comes back empty, and ContentLength is null. Thus, my streamText variable in the test is an empty string.

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

Is it possible to inspect what the middleware is writing to the context in this situation? Is this the appropriate way, or is there a better way.

推荐答案

考虑自己设置 body 以便您可以控制流

Consider setting the body yourself so that you have control of the stream

@AndrewStanton-Nurse 提供的评论

Comment provided by @AndrewStanton-Nurse

DefaultHttpContext 中的 Response.Body 流是 Stream.Null,这是一个忽略所有读/写的流.调用方法前需要自己设置Stream.

进一步 - 现在允许设置正文,但为了正确读取它,我们必须按照 这个答案,在使用 StreamReader 之前.

Further - This will now allow the body to be set, but in order to read it correctly we must set the pointer to the beginning as per this answer, before using the 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

这篇关于在单元测试情况下检查 DefaultHttpContext 主体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 01:39