Mock HttpContext для модульного тестирования основного ядра MVC-контроллера .NET?

У меня есть функция в контроллере, которая является модульным тестированием, которое ожидает значения в заголовке HTTP-запроса. Я не могу инициализировать HttpContext, потому что он только для чтения.

Моя функция контроллера ожидает значения заголовка запроса http для "device-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);
}

Есть ли прямой способ сделать это без использования сторонней библиотеки?

Ответы

Ответ 1

Я смог инициализировать 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 recieves the http header key value pair device-id:20317
    ...
}

Ответ 2

Вместо того, чтобы издеваться над HTTPContext, вероятно, лучше всего отобразить заголовок в параметр метода. Например, в контроллере в нижней части этого ответа параметр id устанавливается в заголовок значения с именем, равным "идентификатор устройства"... unit test затем становится

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

Пока вы можете высмеивать HttpContext, по-моему, этого следует избегать, если у вас нет выбора. Документацию для FromHeaderAttribute можно найти здесь FromHeaderAttribute Class.

    public class ValuesController: Controller
    {

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