.NET: как я могу тестировать этот метод? - PullRequest
2 голосов
/ 18 ноября 2010

(По аналогии с .NET как выдумать объект HttpContext !)

У меня есть метод, который я хочу проверить:

    public void MyMethod()
    {
        if (HttpContext.Current.Application["myValue"] != null)
            Console.WriteLine("Boo!");
    }

Как я могу написать тест БЕЗ рефакторинга метода, чтобы ударить Console.WriteLine?

Я пытался с:

        TextWriter tw = new StringWriter();
        HttpWorkerRequest wr = new SimpleWorkerRequest("/webapp", @"path...", "logon.asp", "", tw);
        HttpContext.Current = new HttpContext(wr);
        HttpContext.Current.Application.Add("KeyValue", "myValue");
        MyMethod();

но HttpContext.Current.Application.count всегда равен нулю, я не могу добавить к нему значения!

Ответы [ 4 ]

4 голосов
/ 18 ноября 2010

Дело в том, что вы должны реорганизовать этот метод, чтобы его было проще тестировать! Чтобы правильно проверить это, вы хотите смоделировать HttpContext (вот один пример того, как: Как использовать Rhino Mocks для насмешки HttpContext.Application ).

3 голосов
/ 15 марта 2011

Вы можете использовать HttpSimulator класс из www.koders.com - Subtext.TestLibrary

Просто вызывает

new Subtext.TestLibrary.HttpSimulator().SimulateRequest();

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

Как сказал Джефф, он устанавливает HttpApplicationFactory._theApplicationFactory._state, используя Reflection, как показано ниже, но на самом деле вам не нужно об этом беспокоиться.

Type appFactoryType = Type.GetType("System.Web.HttpApplicationFactory, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
object appFactory = ReflectionHelper.GetStaticFieldValue<object>("_theApplicationFactory", appFactoryType);
ReflectionHelper.SetPrivateInstanceFieldValue("_state", appFactory, HttpContext.Current.Application);
3 голосов
/ 18 ноября 2010

Если вам специально запрещено проводить рефакторинг метода, а также необходимо его протестировать, вы можете использовать обходную систему, такую ​​как Крот или TypeMock Isolator , для полного обхода статические и HttpContext вызовы. Однако это может показаться немного уродливым, и гораздо предпочтительнее выполнить рефакторинг исходного кода.


Последовательность отклоненных насмешек будет:

  1. Обход HttpContext.Current для возврата заглушки обхода HttpContext (ваша собственная реализация, соответствующая интерфейсу класса HttpContext, но похожая на HttpContext для тестируемого кода.)

  2. В своей заглушке HttpContext, смоделируйте Application ["myValue"], чтобы вернуть желаемое значение (в данном случае нулевое или ненулевое). Это, вероятно, потребует создания обходного класса для возвращаемого значения Application .

  3. Теперь вы можете настроить объезд и запустить свой метод. Вызовы методов HttpContext.Current и HttpContext будут перенаправлены через API профилирования на ваши заглушки.

0 голосов
/ 18 ноября 2010

HttpContext.Application предоставляется частным синглтоном, к которому у вас нет нормального доступа.

Вы можете установить это с помощью рефлексии, но я лично даже не стал бы беспокоиться,

Вместо этого вы должны изолировать свой тестируемый код от глобального состояния, например HttpContext.Current: просто передайте искомое значение в метод, который вы хотите протестировать.

Вы можете ясно увидеть проблемуглядя на код в Reflector (или в исходном коде .NET, если вы его скачали): HttpContext.Application метод доступа get возвращает новый HttpApplicationState экземпляр каждый раз, когда вы вызываете его если что-то (например, платформа ASP.NET) не устанавливает HttpApplicationFactory._theApplicationFactory._state.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...