在单元测试中模拟HTTPResponse

时间:2010-12-29 09:21:11

标签: c# testing nunit mocking httpresponse

我正在尝试为一些遗留代码创建单元测试。 我必须测试的一个类叫做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

Click this

有了这个,我可以在测试执行期间获得一个假的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:使用自定义TextWriter时,OutputStream不可用。

我不确定我究竟应该在这里断言...因此在测试中没有断言。 这是测试这种方法的正确方法......任何想法。请指教?

由于

3 个答案:

答案 0 :(得分:4)

测试它的另一种方法是使用抽象基类,如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.
...
}

对于真实上下文,您只需创建存根并委托给可测试方法,例如:

public void Transmit(string fileName, HttpResponse response, DownloadFileType fileType, byte[] content)
{
   var requestWrapper = new HttpResponseWrapper(response);
   this.Transmit(fileName, requestWrapper, fileType, content);
}

答案 1 :(得分:1)

在我的项目中,我们成功地将HttpSimulator用于此目的:

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

答案 2 :(得分:0)

谢谢大家...... 其实我应该一直使用假的HttpContext的响应 我创建了..而不是创建一个新的Response对象:

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

这有效!!!!