2017-08-30 1 views
5

J'essaie d'utiliser l'objet DefaultHttpContext pour tester mon intergiciel de gestion des exceptions.Inspecter le corps DefaultHttpContext en situation de test unitaire

Ma méthode de test ressemble à ceci:

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

Dans mon middleware, je vous écris au contexte comme celui-ci:

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

Pour vous donner une meilleure idée de l'approche middleware j'ai pris, je prends l'approche trouvée dans this answer here. Fonctionne correctement lorsque l'application est en cours d'exécution son pipeline normal. Cependant, en utilisant la méthode DefaultHttpContext dans le test, le corps de réponse revient toujours vide et ContentLength est null. Ainsi, ma variable streamText dans le test est une chaîne vide.

Est-il possible d'inspecter ce que le middleware écrit dans ce contexte? Est-ce le bon moyen, ou existe-t-il un meilleur moyen?

+0

Que se passe-t-il dans votre middleWare.Invoke()? Peut-être que vous n'appelez pas WriteResponse() ici. – Kostya

Répondre

4

Envisager de mettre le corps vous afin que vous avez le contrôle du flux

Commentaire fourni par @ AndrewStanton-infirmière

Le flux Response.Body dans DefaultHttpContext est Stream.Null, qui est un flux qui ne tient pas compte de toutes les lectures/écrit. Vous devez définir le flux avant d'appeler la méthode.

De plus - Cela maintenant permettre au corps à régler, mais pour le lire correctement il faut régler le pointeur au début comme par this answer, avant d'utiliser le 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

Ceci est la solution. Le flux Body dans DefaultHttpContext est Stream.Null, qui est un flux qui ignore toutes les lectures/écritures. Vous devez définir le flux avant d'appeler la méthode. –