Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在单元测试情况下检查DefaultHttpContext主体_C#_Unit Testing_Asp.net Core_.net Core_Moq - Fatal编程技术网

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

C# 在单元测试情况下检查DefaultHttpContext主体,c#,unit-testing,asp.net-core,.net-core,moq,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 = n

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


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

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

由@AndrewStanton Nurse提供的评论

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

进一步-这将允许设置主体,但为了正确读取主体,我们必须在使用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

中间件中发生了什么。Invoke()?也许你只是不在那里调用WriteResponse(),这就是解决方案。DefaultHttpContext中的主体流是stream.Null,它是一个忽略所有读/写的流。在调用方法之前,您需要自己设置流。