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


95

私はユニットテストであるコントローラーに、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);
}

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


1
HttpContextを使用しないのですか?コントローラを使用する重要な点は、データがコントローラのパラメータを介して送信されることです。コントローラーがHttpContextを使用して、Webフォームページであるかのようにデータを読み取る場合、問題が発生します。
Panagiotis Kanavos 16

@PanagiotisKanavosヘッダーの値は、呼び出しがどのモバイルデバイスからのものかを示す情報です。これは、正しいデータを取得するために必要です。IDは認証に必要なため、ヘッダーにデバイスIDが含まれています。認証はカスタムアクションフィルターによって処理されます。デバイスIDをルートパラメータとして渡すこともできましたが、冗長になります
James Wierzba

FromHeaderAttributeを確認しますが、重複も確認します。現在、HttpContextは構成を介して注入可能
Panagiotis Kanavos

1
質問を編集して、必要なものを正確に指定することをお勧めします(モバイルデバイスを識別するためのヘッダーフィールドへのアクセス)。ASP.NETドキュメントは、親切に言うと.... "移行"期間を経ているようで、ドキュメントページがありません。モバイルデバイスをルーティングする方法を尋ねるこのほぼ同じ質問を確認してください
Panagiotis Kanavos 2016

回答:


227

私はこの方法で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
    ...
}

21

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

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

HttpContext モックすることはできます、私の意見では、選択の余地がない限り回避する必要があると思います。FromHeaderAttributeのドキュメントは、FromHeaderAttributeクラスにあります。

public class ValuesController: Controller
{
    public string GetHeaderValue([FromHeader(Name = "device-id")] string id)
    {
        return id;
    }
}

1
私の場合、IIRC、.netコアミドルウェアコンポーネントで同じ値を評価する必要があるため、httpヘッダーに含める必要がありました
James Wierzba
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.