Построение HttpContext для тестирования, как я могу указать HttpRequest, является POST?

Я пишу некоторые модульные тесты для метода, который использует HttpContext в качестве параметра. Я хочу проверить, что поведение ожидаемо, когда запрос является POST.

При создании System.Net.HttpWebRequest легко установить метод, но я не вижу способа указать метод при создании System.Web.HttpRequest, который используется в HttpContext.

Любые идеи?

Для контекста метод вызывается httphandler, и он должен вызывать 405, если запрос не является POST. Я знаю, что могу фильтровать допустимые методы с помощью свойства Verbs в файле web.config, но я не буду останавливать кого-то в будущем от изменения свойства глаголов, чтобы разрешить другие методы, в этом случае я хочу, чтобы обработчик выполнял его самого.

Вспомогательный метод, используемый в настоящее время:

    private HttpContext GetHttpContext(string requestUrl)
    {
        var httpRequest = new HttpRequest("", requestUrl, "");            
        var stringWriter = new StringWriter();
        var httpResponce = new HttpResponse(stringWriter);
        return new HttpContext(httpRequest, httpResponce);
    }

Ответ 1

Я бы рекомендовал исследовать насмешливые объекты для модульного тестирования. Для .NET есть несколько фальшивых фреймворков, которые облегчают именно этот тип тестов.

Например, статья здесь устанавливает HttpMethod с использованием инфраструктуры Moq.

Из статьи:

public ContextMocks(Controller onController, string HTTPMethod)
{
    //...
    Request = new Moq.Mock<HttpRequestBase>();
    Request.Setup(x => x.HttpMethod).Returns(HTTPMethod);
    //...
}

Тем не менее, если это одноразовый тест, и я не могу подчеркнуть это достаточно, и накладные расходы, вызванные тем, что вы вводите объект в насмешку, не нужны в вашей конкретной ситуации, следующее отражение задает HttpMethod:

typeof(HttpRequest).GetField("_httpMethod", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(httpRequest, "POST");

Как я упоминал ранее, если тестирование с помощью HttpContext, HttpRequest и т.д. станет или станет повторяющейся темой, тогда воспользуйтесь издевательской структурой. Вы сэкономите время в долгосрочной перспективе.