Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Thursday, February 18, 2016

Unit test for a method that takes a HttpResponse object as a parameter. OutputStream is not available

Unit test for a method that takes a HttpResponse object as a parameter. OutputStream is not available


I am trying to create a unit test for a method that takes a HttpResponse object as a parameter. What the correct way of doing this? I hope you seasoned unit testers out there can help me.

Additional information: I tried creating a fake HttpResponse object by passing in a StringWriter.

StringBuilder sb = new StringBuilder();  StringWriter sw = new StringWriter(sb);  HttpResponse response = new HttpResponse(sw);  RssGenerator.Generate(response, otherParameters);  

The test fails with the message: System.Web.HttpException: OutputStream is not available when a custom TextWriter is used. The method being tested is part of a class library dll. It uses the Response object's OutputStream to create an RSSFeed with an XMLWriter.

Answer by crunchdog for Unit test for a method that takes a HttpResponse object as a parameter. OutputStream is not available


To be truly unit, you should mock HttpResponse and everything else to only test your methods code. I don't know of any C# mocking utilities, but this question might help.

You can then do something like this (example is Java with Mockito):

HttpResponse response = mock(HttpResponse.class);  OutputStream outputStream = mock(OutputStream.class);  when(response.getOutputStream()).thenReturn(outputStream);     RssGenerator.generate(response, otherParameters);  

Of course, you probably need to configure your mock more than this, but you get the general idea.

Answer by Guffa for Unit test for a method that takes a HttpResponse object as a parameter. OutputStream is not available


The constructor for HttpResponse isn't intended for your use, it's only there for the ASP.NET page cycle to use, so there is no documentation on how to create one.

You have to set up the HttpResponse object so that it uses an HttpWriter, otherwise it won't let you access the underlying stream. However, the constructor set the _httpWriter variable to null, so you have to find some other way to set it.

You can use the .NET Reflector program to dig around in the HttpResponse class and see what it does.

Answer by Rodney Gitzel for Unit test for a method that takes a HttpResponse object as a parameter. OutputStream is not available


If I couldn't refactor the method signature (perhaps the method really only needs one value from the HttpResponse?), I would have Eclipse generate a null implementation of HttpResponse (yes, I'm in Java, but it's the same idea) -- i.e. implements all the methods returning null -- and simply fill in just the ones I need in the method to be tested, and have them return some constant values. (Yeah, could use a mocking framework of some sort, too.)

The reason you can't create your own instance of the existing implementation is it will be heavily tied to your application server, and will likely need all sorts of other gunk to even be instantiated.

If it turned out I need something more complicated than a simple null version of HttpResponse, then I would look at NOT testing this method directly: perhaps a test one or two levels up would be simpler and would provide me the same level of confidence in the code.

Answer by ryber for Unit test for a method that takes a HttpResponse object as a parameter. OutputStream is not available


So the problem with Mocking HttpResponse is that it's sealed so you cant extend it (and most mocking frameworks that Mock concrete classes just overwrite virtual methods). Microsoft was also kind enough to not provide interfaces for most of these...so thanks MS.

For this reason (amongst others) I usually end up writing my own Interfaces for all the sealed MS classes and then writing wrapper implementations that take the MS class in the constructor and shunt them in as soon as possible in the request. Then you can create mocks of the interfaces and have them do whatever you like.

Answer by Frank Schwieterman for Unit test for a method that takes a HttpResponse object as a parameter. OutputStream is not available


Need to use namespace System.Web.Abstractions

In particular, take a HttpResponseBase (http://msdn.microsoft.com/en-us/library/system.web.httpresponsebase.aspx) as an input parameter instead of HttpResponse. Then you can mock the HttpResponseBase from your tests. When you have a real HttpResponse to pass in, use HttpResponseWrapper to produce a HttpResponseBase.

Answer by Riga for Unit test for a method that takes a HttpResponse object as a parameter. OutputStream is not available


If you want a more detailed answer, here is what I ended doing in my project:

_mockResponse = new Mock();  _contentType = string.Empty;  _mockResponse.SetupSet(r => r.ContentType = It.IsAny()).Callback(value => _contentType = value);  _header = new KeyValuePair();  _mockResponse.Setup(r => r.AddHeader(It.IsAny(), It.IsAny())).Callback((string name, string value) => _header = new KeyValuePair(name, value));  _writer = new StringBuilder();  _mockResponse.Setup(r => r.Write(It.IsAny())).Callback(s => _writer.Append(s));  var data = "This is the string to send as response";    UTIL.SendStringAsHttpResponse(data, _mockResponse.Object);    Assert.That(_contentType, Is.EqualTo("application/CSV"));  Assert.That(_header.Value, Is.EqualTo("attachment; filename=download.csv"));  Assert.That(_writer.ToString(), Is.EqualTo(data));  

where SendStringAsHttpResponse is defined as

public static void SendStringAsHttpResponse(string data, HttpResponseBase response)  


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.