Знущається з HttpContext для модульного тестування контролера MVC основного .NET?


94

У мене є функція в контролері, я тестую модуль, яка очікує значення в заголовку запиту http. Я не можу ініціалізувати HttpContext, оскільки він призначений лише для читання.

Моя функція контролера очікує значення заголовка запиту 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 для зчитування даних так, ніби це сторінка WebForms, у вас проблема.
Панайотис Канавос

@PanagiotisKanavos Значення в заголовку - це інформація, яка вказує, з якого мобільного пристрою здійснюється дзвінок. Це потрібно для отримання правильних даних. Ідентифікатор пристрою міститься у заголовку, оскільки ідентифікатор необхідний для автентифікації, яка обробляється спеціальним фільтром дій. Я міг би передати ідентифікатор пристрою як параметр маршруту, але це було б зайвим
James Wierzba

Позначте FromHeaderAttribute, але також перевірте дублікат. HttpContext зараз можна вводити через конфігурацію
Panagiotis Kanavos

1
Я пропоную вам відредагувати своє запитання, щоб точно вказати, що ви хочете (доступ до полів заголовка для ідентифікації мобільних пристроїв). Документація ASP.NET, мабуть, переживає .... "перехідний" період, відсутні сторінки документації. Перевірте це майже ідентичне запитання, яке задає питання про маршрутизацію мобільних пристроїв
Panagiotis Kanavos

Відповіді:


226

Мені вдалося ініціалізувати 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параметру встановлюється заголовок значення з іменем, що дорівнює "ідентифікатор пристрою" ... Потім одиничний тест стає

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

1
У моєму випадку, IIRC, була вимога включити його в заголовок http, оскільки те саме значення потрібно було оцінити в основному компоненті проміжного програмного забезпечення .net
James Wierzba,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.