Inspect the body of DefaultHttpContext in unit test

I am trying to use the DefaultHttpContext object for the unit test of my middleware to handle exceptions.

My verification method is as follows:

 [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 write in context as follows:

 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 information about the middleware approach that I took, I use the approach found in here, here .

Works well when the application starts a regular pipeline. However, using the DefaultHttpContext method in the test, the response body is always returned empty, and ContentLength is null. So my streamText variable in the test is an empty string.

Is it possible to verify that middleware writes in context in this situation? Is this right, or is there a better way.

+5
source share
1 answer

Consider body tuning yourself so that you control the flow

Comment provided by @ AndrewStanton-Nurse

The Response.Body stream in DefaultHttpContext is Stream.Null , which is a stream that ignores all reads / writes. Before calling the method, you need to install Stream.

Further - now it will allow us to install the body, but for its proper reading we must set the pointer to the beginning in accordance with this answer before using 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 
+4
source

Source: https://habr.com/ru/post/1271363/


All Articles