web-dev-qa-db-fra.com

Mock HttpContext pour les tests unitaires d'un contrôleur MVC central .NET?

J'ai une fonction dans un contrôleur que je suis en train de tester qui attend des valeurs dans l'en-tête de la requête http. Je ne peux pas initialiser le HttpContext parce qu'il est en lecture seule.

Ma fonction de contrôleur attend une valeur d'en-tête de demande http pour "ID-appareil"

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

Existe-t-il un moyen simple de faire cela sans utiliser une bibliothèque tierce?

62
James Wierzba

J'ai pu initialiser le httpcontext et l'en-tête de cette façon:

[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

Plutôt que de simuler HTTPContext, il est probablement préférable de mapper l'en-tête dans un paramètre de la méthode. Par exemple, dans le contrôleur au bas de cette réponse, le paramètre id est défini sur l'en-tête de valeur avec un nom égal à "ID-appareil" ... Le test unitaire devient alors

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

Tandis que vous pouvez vous moquer du HttpContext, à mon avis c'est quelque chose qui devrait être évité sauf si vous n'avez pas le choix. La documentation de FromHeaderAttribute est disponible ici FromHeaderAttribute Class .

    public class ValuesController: Controller
    {

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