在单元测试中模拟HTTPResponse

Sen*_*nin 6 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();
}
Run Code Online (Sandbox Code Playgroud)

我不允许重构这个代码(这本来是理想的!).

为了测试这个,我决定根据下面的文章创建一个假的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);
}
Run Code Online (Sandbox Code Playgroud)

我正在将自定义创建的HTTPResponse对象传递给该方法.当它命中"response.BinaryWrite(content)"行时抛出以下异常:

System.Web.HttpException:使用自定义TextWriter时,OutputStream不可用.

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

谢谢

asa*_*asa 5

另一种测试方法是使用抽象基类,如 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.
...
}
Run Code Online (Sandbox Code Playgroud)

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

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


Ale*_*sky 1

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

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