2016-12-30 5 views
20

Ich habe eine Funktion in einem Controller, der Unit-Tests, die Werte in der Kopfzeile der HTTP-Anfrage erwartet. Ich kann den HttpContext nicht initialisieren, weil er schreibgeschützt ist.Mock HttpContext für Unit-Test einen .NET Core MVC Controller?

Meine Controller Funktion erwartet einen HTTP-Request-Header-Wert 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 geradlinige Art und Weise, dies zu tun, ohne einen Dritten Bibliothek?

+0

* Verwenden Sie nicht HttpContext? Der entscheidende Punkt bei der Verwendung von Controllern ist, dass die Daten die Parameter des Controllers durchlaufen. Wenn Ihr Controller den HttpContext zum Lesen von Daten verwendet, als wäre es eine WebForms-Seite, liegt ein Problem vor. –

+0

@PanagiotisKanavos Der Wert in der Kopfzeile ist eine Information, aus welchem ​​Mobilgerät der Anruf stammt. Dies ist erforderlich, um die korrekten Daten abzurufen. Die Geräte-ID befindet sich in der Kopfzeile, da die ID für die Authentifizierung benötigt wird, die von einem benutzerdefinierten Aktionsfilter verarbeitet wird. Ich könnte die Geräte-ID als Route Parameter übergeben, aber es wäre redundant –

+0

Check FromHeaderAttribute, sondern auch das Duplikat überprüfen. HttpContext ist durch Konfiguration jetzt injizierbar –

Antwort

56

konnte ich die Httpcontext und Header auf diese Weise 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 recieves the http header key value pair device-id:20317 
    ... 
} 
5

Anstatt die Httpcontext spöttisch aus, es ist wahrscheinlich eine bessere Idee den Header in einen Parameter für das Verfahren abzubilden. Zum Beispiel in der Steuerung an der Unterseite dieser Antwort, die id Parameter auf den Wert Header mit einem Namen gleich „Geräte-ID“ ist für ... Der Unit-Test wird dann

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

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

public class ValuesController: Controller 
    { 

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

In meinem Fall, IIRC, war es eine Voraussetzung, es in HTTP-Header aufzunehmen, da der gleiche Wert ausgewertet werden musste in einer .net-Core-Middleware-Komponente –

Verwandte Themen