2017-08-30 14 views
5

DefaultHttpContextオブジェクトを使用して、私の例外処理ミドルウェアをユニットテストしようとしています。ユニットテスト状況で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)); 
} 

私はしました私はthis answer hereにあるアプローチを取っています。

アプリケーションが通常のパイプラインを実行しているときにうまく動作します。ただし、テストでDefaultHttpContextメソッドを使用すると、応答本体は常に空に戻り、ContentLengthはnullになります。したがって、私のstreamText変数は空文字列です。

この状況で、ミドルウェアがコンテキストに書き込んでいる内容を調べることは可能ですか?これは適切な方法ですか、より良い方法がありますか?あなたは、ストリームの制御を持っているように、

+0

あなたのミドルウェアではどうなりますか? WriteResponse()を呼び出さないでください。 – Kostya

答えて

4

は身体を自分で設定を検討@ AndrewStanton、看護師が提供する

コメント

DefaultHttpContextResponse.Bodyストリームは、すべての読み込みを無視したストリームであるStream.Null、あります/書き込み。メソッドを呼び出す前にストリームを自分で設定する必要があります。

さらに - これは、今の体が設定することができますが、それを正しく読むために、私たちはのStreamReaderを使用する前に、this answerごとに先頭にポインタを設定する必要があります。

//...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

これが解決策です。 DefaultHttpContextのBodyストリームはStream.Nullです。これはすべての読み書きを無視するストリームです。メソッドを呼び出す前にストリームを自分で設定する必要があります。 –

関連する問題