web-dev-qa-db-ja.com

.NETコアMVCコントローラーの単体テスト用のHttpContextをモックしますか?

私は、HTTPリクエストのヘッダーに値を期待するユニットテストであるコントローラに機能があります。 HttpContextは読み取り専用なので初期化できません。

私のコントローラー関数は、「device-id」のhttpリクエストヘッダー値を期待しています

[TestMethod]
public void TestValuesController()
{
    ValuesController controller = new ValuesController();

    //not valid controller.HttpContext is readonly
    //controller.HttpContext = new DefaultHttpContext(); 

    var result = controller.Get();
    Assert.AreEqual(result.Count(), 2);
}

サードパーティのライブラリを使用せずにこれを行う簡単な方法はありますか?

62
James Wierzba

この方法でhttpcontextとヘッダーを初期化できました。

[TestMethod]
public void TestValuesController()
{
    ValuesController controller = new ValuesController();
    controller.ControllerContext = new ControllerContext();
    controller.ControllerContext.HttpContext = new DefaultHttpContext();
    controller.ControllerContext.HttpContext.Request.Headers["device-id"] = "20317";
    var result = controller.Get();
    //the controller correctly receives the http header key value pair device-id:20317
    ...
}
159
James Wierzba

HTTPContextをモックアウトするよりも、おそらくヘッダーをメソッドのパラメーターにマップする方が良いでしょう。たとえば、この回答の下部にあるコントローラーでは、idパラメーターが「device-id」に等しい名前の値ヘッダーに設定されます...

[TestMethod]
public void TestValuesController()
{
    ValuesController controller = new ValuesController();
    var result = controller.GetHeaderValue("27");
    Assert.AreEqual(result, "27");
}

あなたはcanHttpContextをモックできますが、私の意見では、選択の余地がない限り避けるべきです。 FromHeaderAttributeのドキュメントは、ここにあります FromHeaderAttribute Class

    public class ValuesController: Controller
    {

      public string GetHeaderValue([FromHeader(Name = "device-id")] string id)
      {
        return id;
      }
    }
15
GlennSills