Mocking HTTPResponse в модульном тесте - PullRequest
6 голосов
/ 29 декабря 2010

Я пытаюсь создать модульные тесты для некоторого устаревшего кода.Один из классов, который я должен протестировать, называется FileDownloader, который имеет только один следующий метод:

public void Transmit(string fileName, HttpResponse response, DownloadFileType fileType, byte[] content)
{
    response.Clear();
    response.ClearHeaders();
    response.ContentType = "application/xls";
    response.AddHeader("content-disposition", "attachment; filename=" + HttpContext.Current.Server.UrlEncode(fileName));
    response.BinaryWrite(content);
    response.End();
    response.Flush();
}

Мне не разрешено рефакторинг этого кода (что было бы идеально!).

Чтобы проверить это, я решил создать поддельный HttpContext на основе статьи ниже

Щелкните по этому

С этим я могу получить поддельный HttpContext во времявыполнение моего теста, однако есть проблемы с подделкой HttpResponse.

Вот как выглядит мой тест:

[SetUp]
public void SetUp()
{
    mocks = new MockRepository();            
    FakeHttpContext.CreateFakeHttpContext();
}

[Test]
public void ShouldTransmitHttpResponseInTheSpecifiedFormat()
{
    FileDownloader downloader = new FileDownloader();
    string path = "..\\..\\Fakes\\DummyDownloadReportsTemplate.xls";
    byte[] bytes = ReadByteArrayFromFile(path);
    downloader.Transmit("test.xls", new HttpResponse(new StringWriter()), DownloadFileType.Excel, bytes);
}

Я передаю в метод созданный пользователем объект HTTPResponse.Это вызывает следующее исключение при попадании в строку «response.BinaryWrite (content)»:

System.Web.HttpException: OutputStream недоступен, когда используется пользовательский TextWriter.

I 'я не уверен, что именно я должен утверждать здесь .. следовательно, нет никаких утверждений в тесте.Это правильный способ проверить этот метод ... любые идеи.посоветуйте пожалуйста?

спасибо

Ответы [ 3 ]

4 голосов
/ 30 декабря 2010

Другой способ тестирования - использование абстрактных базовых классов, таких как HttpContextBase, HttpResponseBase и т. Д. http://msdn.microsoft.com/en-us/library/system.web.httpcontextbase(v=VS.90).aspx

HttpContextBase является частью .NET 3.5 SP1, .NET 4.0 и может быть установлен как отдельный пакет.для .NET 2.0.Когда я тестировал загрузку / загрузку обработчиков, эта функция показалась мне исправлением: -).

Использование просто.Этот метод будет покрыт тестом.

public void Transmit(string fileName, HttpResponseBase response, DownloadFileType fileType, byte[] content)
{
...
// main logic.
...
}

Для реального контекста вы можете просто создать заглушку и делегировать методу testtable, например:

public void Transmit(string fileName, HttpResponse response, DownloadFileType fileType, byte[] content)
{
   var requestWrapper = new HttpResponseWrapper(response);
   this.Transmit(fileName, requestWrapper, fileType, content);
}
1 голос
/ 29 декабря 2010

В моем проекте мы успешно используем HttpSimulator для таких целей:

http://haacked.com/archive/2007/06/19/unit-tests-web-code-without-a-web-server-using-httpsimulator.aspx

0 голосов
/ 07 января 2011

Спасибо всем .. На самом деле я должен был использовать Response поддельного HttpContext, который я создал .. вместо создания нового объекта Response:

 downloader.Transmit("test.xls", HttpContext.Current.Response, DownloadFileType.Excel, bytes);

это работает !!!!

...