2010-11-18 3 views
2

(! Подобно .NET how to fudge the HttpContext object).NET: как я могу проверить этот метод?

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

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 всегда равна нулю, я не могу добавить значения к нему!

+0

Отказывание HttpContext очень сложно. Если вы не можете реорганизовать или переработать это, попробуйте насмешливую структуру. – Steven

+0

Привет, Стивен. Попробуйте насмешливую структуру? Если вы думаете, что я могу это сделать без рефакторинга метода, напишите annwer и explane. Я не думаю, что возможно – Bob

ответ

3

Вы можете использовать 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); 
4

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

+1

+1 - или еще лучше, передайте значение, содержащееся в 'HttpContext.Current.Application [" myValue "]'. –

+0

Если я реорганизую метод, то у меня нет проблем с его тестированием. Всегда есть причины, по которым вы не сможете реорганизовать метод, например. seniour management сказать НЕТ. Так ответ на мой вопрос нет, это невозможно сделать? – Bob

0

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

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

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

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

3

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


Последовательность издевается свернуть будет:

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

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

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

Смежные вопросы