2017-08-30 83 views
5

Próbuję użyć obiektu DefaultHttpContext do przetestowania mojego oprogramowania obsługi wyjątków.Sprawdzanie treści DefaultHttpContext w jednostkowej sytuacji testu

Moja metoda badawcza wygląda następująco:

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

W moim middleware, piszę w kontekście tak:

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

Aby dać lepszy wgląd w podejściu middleware mam podjęte, przyjmuję podejście znalezione w this answer here.

Działa prawidłowo, gdy aplikacja uruchamia normalny potok. Jednak przy użyciu metody DefaultHttpContext w teście treść odpowiedzi zawsze jest pusta, a wartość ContentLength ma wartość NULL. Zatem zmienna streamText w teście jest pustym ciągiem.

Czy można sprawdzić, co program pośredniczący pisze w kontekście w tej sytuacji? Czy to odpowiedni sposób, czy jest lepszy sposób?

+0

Co dzieje się w twoim middleWare.Invoke()? Może po prostu nie wywołasz WriteResponse() tam. – Kostya

Odpowiedz

4

rozważyć ustawienie ciału siebie tak, że masz kontrolę nad strumieniem

Komentarz dostarczonych przez @ AndrewStanton-Nurse

Response.Body strumień w DefaultHttpContext jest Stream.Null, który jest strumieniem, który ignoruje wszystko czyta/pisze. Przed wywołaniem metody musisz ustawić Strumień.

dalej - To będzie teraz pozwolić organizmowi być ustawiony, ale aby ją przeczytać poprawnie musimy ustawić kursor na początku, jak na this answer, przed użyciem 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

To jest rozwiązanie. Strumień Ciała w DefaultHttpContext to Stream.Null, który jest strumieniem, który ignoruje wszystkie odczyty/zapisy. Przed wywołaniem metody musisz ustawić Strumień. –