c# - 在单元测试情况下检查 DefaultHttpContext 主体

标签 c# unit-testing asp.net-core .net-core moq

我正在尝试使用 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 为 null。因此,我在测试中的 streamText 变量是一个空字符串。

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

最佳答案

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

@AndrewStanton-Nurse 提供的评论

The Response.Body stream in DefaultHttpContext is Stream.Null, which is a stream that ignores all reads/writes. You need to set the Stream yourself before calling the method.

进一步 - 这现在允许设置正文,但为了正确读取它,我们必须根据 this answer 将指针设置为开头, 在使用 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

关于c# - 在单元测试情况下检查 DefaultHttpContext 主体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45959605/

相关文章:

c# - 使用相同泛型类型的另一个依赖项注册装饰器

c# - 发送时无法立即完成非阻塞套接字操作

c# - 单元测试屏幕刮刀

javascript - 在 ASP.NET MVC Core 中跨页面更改保留 JavaScript 设置

angular - ASP .Net Core 3.1 Angular 模板不起作用

c# - 当你的算法已经处理它时处理 "not all code paths return a value"的技术

c# - 为 URI 关联注册应用程序 (Windows Phone 8.1 RT)

c# - NUnit 单元测试有 "ExpectedException"但仍然因异常而失败

c# - 有没有更好的方法用最小起订量编写这个测试?

asp.net-core - 更新 Mac OSX 中的 dotnet cli