1

Я видел следующие вопросы уже:Как протестировать модульный код, который зависит от HttpWebRequest и HttpWebResponse?

Они не помогают мне, потому что мне нужно:

  1. Чтобы проверить существующий код который использует WebRequest/WebResponse напрямую, без интерфейсов
  2. Существующий код зависит от HttpWebRequest/HttpWebResponse, поэтому я не могу использовать свои собственные классы WebRequest и WebResponse.

Я знаю о WebRequest.RegisterPrefix и успешно прошел единичный тест, который доказывает, что он работает (как только вы получите префикс справа). Но этот тест просто проверяет WebRequest и WebResponse.

Я попытался следующие, но это дает ошибку компиляции (а не предупреждение):

public class MockWebRequest : HttpWebRequest 
{ 
    public MockWebRequest() 
    // : base(new SerializationInfo(typeof (HttpWebRequest), new FormatterConverter()), 
    //  new StreamingContext()) 
    { 
    } 
} 

С двумя линиями закомментированный, я получаю ошибку компиляции:

error CS0619: 'System.Net.HttpWebRequest.HttpWebRequest()' is obsolete: 'This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.'

Когда Я раскомментируйте эти строки, я получаю 618 предупреждение, но код сбой во время выполнения:

System.Runtime.Serialization.SerializationException: Member '_HttpRequestHeaders' was not found. 
    at System.Runtime.Serialization.SerializationInfo.GetElement(String name, Type& foundType) 
    at System.Runtime.Serialization.SerializationInfo.GetValue(String name, Type type) 
    at System.Net.HttpWebRequest..ctor(SerializationInfo serializationInfo, StreamingContext streamingContext) 
    at UnitTests.MockWebRequest..ctor(String responseJson) 
    at UnitTests.MockWebRequestCreator.Create(Uri uri) 
    at System.Net.WebRequest.Create(Uri requestUri, Boolean useUriBase) 
    at System.Net.WebRequest.Create(Uri requestUri) 
    at code under test 

Я в недоумении о ч ow для продолжения этого (кроме значения по умолчанию, которое нужно просто провести на этих модульных тестах и ​​пожелать, чтобы код был реализован с учетом тестирования).

я мог бы получить «вниз и грязной» и сделать что-нибудь неприятное с ISerializable, или что-то в этом роде, но это вызывает третье требование:

3. Код должен быть ремонтопригодны, и не должно быть слишком много более сложный, чем тестируемый код!

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

ответ

0

Обычно я предпочитаю использовать насмешливую структуру, такую ​​как MOQ, когда насмехаются с asp.net-синглонами, такими как httpcontext.

Есть другие структуры там для насмешливых, но я нахожу MOQ быть очень гибким и интуитивно

https://github.com/Moq/moq4/wiki/Quickstart

Вы можете сделать что-то подобное этому

http://www.syntaxsuccess.com/viewarticle/how-to-mock-httpcontext

Другим подходом заключается в абстрактном вызове httpcontext посредством виртуального метода: Аналогично этой методике: http://unit-testing.net/CurrentArticle/How-To-Remove-Data-Dependencies-In-Unit-Tests.html

+0

К сожалению, для 'HttpWebRequest' нет эквивалента' HttpContextBase'. Нет класса 'HttpWebRequestBase'. –

+0

Хорошо. Я добавил еще один подход, который я иногда использую – TGH

+1

. Я боюсь, что это тоже не поможет. Как я уже сказал в вопросе, я не могу вносить изменения в тестируемый код. –

0

Я просто столкнулся с той же проблемой. Честно говоря, способ, которым Microsoft установил это, не имеет особого смысла - в WebRequest.Create у них есть абстрактная фабрика, но они не предоставляют интерфейсы для HttpWebRequest и HttpWebResponse, которые мы можем реализовать, и не предоставляют защищенный конструктор, который мы можем использовать для наследования от этих классов.

Решение, которое я придумал, требует незначительных изменений в основной программе, но оно работает. В принципе, я делаю то, что Microsoft должна была сделать.

  1. Создание интерфейсов IHttpWebRequest и IHttpWebResponse
  2. создавать фиктивные классы, которые реализуют интерфейсы
  3. Создание оберток для HttpWebRequest и HttpWebResponse, которые реализуют интерфейсы
  4. Заменить вызовы WebRequest.Create с моим собственным заводским способом, который возвращает обертки или издевки, по мере необходимости

В зависимости от того, как структурирован ваш код, приведенное выше может быть относительно тривиальным для imp lement, или это может потребовать внесения изменений в ваш проект. В моем случае у нас есть все наши HTTP-запросы, проходящие через общую службу, поэтому было не так уж плохо.

В любом случае, возможно, слишком поздно для вашего проекта, но, возможно, это поможет кому-то еще по дороге.

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