HttpContext.Current всегда имеет значение null при отправке запроса из модульного теста

У меня есть Web Api controller Action method, я пытаюсь выполнить модульное тестирование. У меня есть один настраиваемый фильтр, который запускается перед этим контроллером действий.

У меня есть вопрос относительно HttpContext.Current.User.Identity.Name, который я использую в своем фильтре пользовательских действий.

Он отлично работает, когда я отправляю свой http-запрос из веб-клиента.

Но когда я отправляю HTTP-запрос из моего модульного теста, чем HttpContext.Current, всегда жалуюсь на null

Не понял где и что не так. Кто-нибудь может объяснить это?

Обратите внимание, что я видел ответы по адресу здесь но не уверен, куда мне нужно добавить этот код в моем случае.


person immirza    schedule 01.05.2016    source источник


Ответы (2)


Модульное тестирование — это не то же самое, что вызов вашего API через веб-клиент.

Когда вы используете веб-клиент, ваш API работает в контексте вашего веб-сервера (например, IIS), и веб-сервер предоставит системе «текущий» HttpContext.

Если вы называете свой код простым и понятным из метода модульного тестирования, вы не работаете в контексте веб-сервера, а вызываете его просто как метод класса. Очевидно, вы можете это сделать, но вам нужно "макетировать" (или подделку, если хотите) текущий HttpContext, чтобы имитировать работу на реальном веб-сервере.

Проверьте этот ответ SO, чтобы узнать, как это сделать.

Кстати, это не тот случай, когда вы запускаете интеграционные тесты (означает вызов реального API через веб-клиент и просто проверяете результаты ввода-вывода): в этом случае вы запускаете свой реальный код в реальном контексте, и все будет работать нормально .

person Luca Ghersi    schedule 02.05.2016

HttpContext.Current не установлен в сценарии с самостоятельным размещением, как в вашем тесте.

Однако вы можете создать оболочку вокруг HttpContext.Current и заполнить ее перед запуском теста. Нравится:

public static class CurrentHttpContext
{
    public static Func<HttpContextBase> Instance = () => new HttpContextWrapper(HttpContext.Current);
}

А затем где-то в тесте, где вы настраиваете HttpSelfHostServer, вы заполняете CurrentHttpContext.Instance. Например, с FakeItEasy (https://github.com/FakeItEasy/FakeItEasy):

var context = A.Fake<HttpContextBase>();
CurrentHttpContext.Instance = () => context;

Затем вы можете получить доступ к CurrentHttpContext.Instance вместо HttpContext.Current в своих фильтрах:

public class MyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var context = CurrentHttpContext.Instance();
        // stuff
    }
}
person peco    schedule 02.05.2016