it-swarm.com.de

Mock HttpContext zum Unit-Testen eines .NET-Kern-MVC-Controllers?

Ich habe eine Funktion in einem Controller, den ich Unit-Tests bin, die Werte im Header der http-Anforderung erwartet. Ich kann den HTTP-Kontext nicht initialisieren, da er schreibgeschützt ist.

Meine Controller-Funktion erwartet einen HTTP-Anforderungsheaderwert für "Geräte-ID".

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

Gibt es eine einfache Möglichkeit, dies zu tun, ohne eine Bibliothek eines Drittanbieters zu verwenden?

62
James Wierzba

Ich konnte den httpcontext und den Header folgendermaßen initialisieren:

[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

Anstatt den HTTPContext zu verspotten, ist es wahrscheinlich eine bessere Idee, den Header einem Parameter in der Methode zuzuordnen. Beispielsweise wird im Controller am Ende dieser Antwort der Parameter id auf den Wertekopf mit dem Namen "Geräte-ID" gesetzt. Der Komponententest wird dann

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

Während Sie den HttpContext verspotten können, ist es meiner Meinung nach etwas, das vermieden werden sollte, es sei denn, Sie haben keine andere Wahl. Die Dokumentation für FromHeaderAttribute finden Sie hier FromHeaderAttribute-Klasse .

    public class ValuesController: Controller
    {

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