我正在针对返回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为null。
有没有人知道如何针对这种类型的控制器编写单元测试用例?
非常感谢!
杰弗里
答案 0 :(得分:4)
您需要mock the 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");
}
答案 1 :(得分: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();
}
}
答案 2 :(得分:1)
这是一个经典的测试问题。它源于这一事实,它更多的是集成测试,而不是单元测试(触摸文件系统)。
模拟HTTP上下文一直是ASP.Net Web Forms时代的一个主要问题。也许你的测试应该关注于HelpPageBusinessService。
如果所有其他方法都失败了,可能会通过依赖注入将助手类传递给控制器,这会将标头或模拟添加到模拟框架中。
答案 3 :(得分: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"));