Mocking HTTPResponse in a unit test
I'm trying to create unit tests for some legacy code . One of the classes that I have to test is called FileDownloader which has just the following one method :
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();
}
I'm not allowed to refactor this code ( which would have been ideal ! ).
To test this I decided to create a fake HttpContext based on the article below
Click this
With this I'm able to get a fake HttpContext during my test execution , however there are issues with faking the HttpResponse .
Here's how my test looks like :
[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);
}
I'm passing a custom created HTTPResponse object to the method. This throws the following exception when it hits the "response.BinaryWrite(content)" line :
System.Web.HttpException : OutputStream is not available when a custom TextWriter is used.
I'm not sure 开发者_开发知识库what exactly should I be asserting here .. hence there no asserts in the test. Is this the correct way to test this method ... any ideas . please advise ?
Thanks
Another way of testing it is using abstract base classes like HttpContextBase, HttpResponseBase, etc. http://msdn.microsoft.com/en-us/library/system.web.httpcontextbase(v=VS.90).aspx
HttpContextBase is a part of .NET 3.5 SP1, .NET 4.0 and can be installed as a separate package for .NET 2.0. When I was testing uploading/downloading handlers that feature had appeared a remedy for me :-).
Usage is simple. This method will be covered with test.
public void Transmit(string fileName, HttpResponseBase response, DownloadFileType fileType, byte[] content)
{
...
// main logic.
...
}
For the real context you can just create a stub and delegate to the testable method, like:
public void Transmit(string fileName, HttpResponse response, DownloadFileType fileType, byte[] content)
{
var requestWrapper = new HttpResponseWrapper(response);
this.Transmit(fileName, requestWrapper, fileType, content);
}
In my project we are successly using HttpSimulator for such purposes:
http://haacked.com/archive/2007/06/19/unit-tests-web-code-without-a-web-server-using-httpsimulator.aspx
Thanks all .. Actually I should have been using the Response of the fake HttpContext that I had created .. instead of creating a new Response object :
downloader.Transmit("test.xls", HttpContext.Current.Response, DownloadFileType.Excel, bytes);
this works !!!!
精彩评论