2

我正在针对返回 pdf 文件的控制器编写测试用例。

控制器代码:

  public FileStreamResult GeneratePdfReport(string context)
    {
        byte[] pdfReportContents = _helpPageBusinessService.GetHelpPagesAsPdf();
        Stream stream = new MemoryStream(pdfReportContents);
        HttpContext.Response.AddHeader("content-disposition", "attachment; filename=GSFA_Help_Pages_Printout.pdf");
        return new FileStreamResult(stream, "application/pdf");
    }

单元测试代码:

 [TestMethod]
    public void GeneratePdf()
    {
        var controller = new HelpController(_helpPageBusinessServiceReportServices, Logger);
        try
        {
            var result = controller.GeneratePdfReport("Work_Request_Section");
            Assert.IsNotNull(result);
            Assert.IsNotNull(result.FileStream);
        }
        finally
        {
            controller.Dispose();
        }
    }

这个单元测试用例不起作用,它总是失败,因为 HttpContext 为空。

有没有人知道如何针对这种类型的控制器编写单元测试用例?

非常感激 !

杰弗里

4

4 回答 4

5

您需要模拟 HttpContext和响应对象。您的控制器操作也可以缩短一点:

public ActionResult GeneratePdfReport(string context)
{
    byte[] pdfReportContents = _helpPageBusinessService.GetHelpPagesAsPdf();
    HttpContext.Response.AddHeader("content-disposition", "attachment; filename=GSFA_Help_Pages_Printout.pdf");
    return File(pdfReportContents, "application/pdf");
}
于 2010-11-02T22:37:28.020 回答
3

按照 Darin Dimitrov 的建议,我提出了以下代码。:)

 [TestMethod]
    public void GeneratePdf()
    {
        var controller = new HelpController(_helpPageBusinessServiceReportServices, Logger);
        var httpContextBase = new Mock<HttpContextBase>
        {
            DefaultValue = DefaultValue.Mock
        };
        var responseObject = Mock.Get(httpContextBase.Object.Response);
        responseObject.Setup(
            s => s.AddHeader("content-disposition", "attachment; filename=GSFA_Help_Pages_Printout.pdf"));
        controller.ControllerContext = new ControllerContext(httpContextBase.Object, new RouteData(), controller);
        try
        {
            var result = controller.GeneratePdfReport("Work_Request_Section");
            Assert.IsNotNull(result);
            Assert.IsNotNull(result.FileStream);
            Assert.IsTrue(result.FileStream.Length == 2000);
        }
        finally
        {
            controller.Dispose();
        }
    }
于 2010-11-02T23:44:57.700 回答
1

这是一个经典的测试问题。它源于这样一个事实,这更像是一个集成测试而不是一个单元测试(涉及文件系统)。

在 ASP.Net Web Forms 时代,模拟 HTTP 上下文一直是一个主要问题。也许您的测试应该集中在 HelpPageBusinessService 上。

如果所有其他方法都失败了,可能会通过依赖注入将一个辅助类传递给您的控制器,这会添加标头或带有模拟框架的模拟。

于 2010-11-02T22:45:03.563 回答
0

使用 MOQ,您甚至可以测试标头是否已实际添加到响应对象中

var httpContextBase = new Mock<HttpContextBase>();
_httpResponse = new Mock<HttpResponseBase>();
httpContextBase.Setup(c => c.Response).Returns(_httpResponse.Object);
controller = new Controller(businessService.Object)
{
     ControllerContext = new ControllerContext { HttpContext = httpContextBase.Object }
};

然后你可以验证

_httpResponse.Verify(r => r.AddHeader("content-disposition", "attachment; filename=GSFA_Help_Pages_Printout.pdf"));
于 2011-06-17T15:47:44.760 回答