Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 239
Sennin Avatar asked Dec 29 '10 09:12

Sennin


People also ask

What is mocking in JUnit testing?

Mocking is a technique of unit testing a class, where we mock an external dependency in order to test our classes and methods. When unit tests are written well with mocks, they would not have any external dependencies and will not fail when external stuff changes.

Does JUnit have mocking?

While doing unit testing using junit you will come across places where you want to mock classes. Mocking is done when you invoke methods of a class that has external communication like database calls or rest calls.

How do you mock the HTTP request?

Mocking ResponsecreateResponse({ eventEmitter: require('events'). EventEmitter }); //Usage: somewhere in tests let next = sinon. spy(); getUsers(request, response, next); response. on('end|data|error', function(error){ //write tests in this close. });


1 Answers

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);
}
like image 83
asa Avatar answered Sep 17 '22 15:09

asa