2017-08-30 15 views
5

Tôi đang cố gắng sử dụng đối tượng DefaultHttpContext để kiểm tra đơn vị phần mềm trung gian xử lý ngoại lệ của mình.Kiểm tra cơ thể mặc địnhHttpContext trong tình huống kiểm tra đơn vị

phương pháp thử nghiệm của tôi trông như thế này:

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

Trong middleware của tôi, Tôi viết thư này với bối cảnh như thế này:

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

Để cung cấp cho bạn cái nhìn sâu sắc hơn vào cách tiếp cận middleware Tôi đã lấy, tôi đang dùng cách tiếp cận được tìm thấy trong this answer here.

Hoạt động tốt khi ứng dụng đang chạy đường ống thông thường. Tuy nhiên, bằng cách sử dụng phương pháp DefaultHttpContext trong thử nghiệm, cơ thể đáp ứng luôn trở lại trống rỗng, và ContentLength là null. Do đó, biến số streamText của tôi trong thử nghiệm là một chuỗi rỗng.

Có thể kiểm tra phần mềm trung gian đang viết cho ngữ cảnh trong tình huống này không? Đây có phải là cách thích hợp hay không, có cách nào tốt hơn không.

+0

Điều gì sẽ xảy ra trong middleWare.Invoke()? Có lẽ bạn chỉ không gọi WriteResponse() ở đó. – Kostya

Trả lời

4

Xem xét đặt cơ thể mình để bạn có quyền kiểm soát của con suối

Comment cung cấp bởi @ AndrewStanton-Y tá

Các Response.Body suối trong DefaultHttpContextStream.Null, mà là một dòng suối mà bỏ qua tất cả các lần đọc/viết. Bạn cần phải tự đặt Luồng trước khi gọi phương thức.

Tiếp tục - Điều này bây giờ sẽ cho phép cơ thể được thiết lập, nhưng để đọc nó một cách chính xác chúng ta phải đặt con trỏ đến đầu theo this answer, trước khi sử dụng 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 
+3

Đây là giải pháp. Dòng Body trong DefaultHttpContext là Stream.Null, là một luồng bỏ qua tất cả các lần đọc/ghi. Bạn cần phải tự đặt Luồng trước khi gọi phương thức. –