Reputation: 199
I am writing a test case against a controller that returns a pdf file.
Code for controller :
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");
}
Unit test code :
[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();
}
}
This unit test case does not work, it always fail as HttpContext is null.
Does anybody out there know how to write unit test case against this type of controller ?
Much appreciated !
Jeffery
Upvotes: 3
Views: 5118
Reputation: 4224
Using MOQ, you can even test if the header has been actually added to the response object
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 }
};
Then you can verify
_httpResponse.Verify(r => r.AddHeader("content-disposition", "attachment; filename=GSFA_Help_Pages_Printout.pdf"));
Upvotes: 0
Reputation: 1038890
You need to mock the HttpContext and the response objects. Also your controller action could be shortened a bit:
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");
}
Upvotes: 6
Reputation: 199
Following Darin Dimitrov's recommendation, I have came up with the following code. :)
[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();
}
}
Upvotes: 4
Reputation: 547
This is a classic testing issue. It stems from the fact this is more of an integration test rather than a unit test (touching the file system).
Mocking HTTP context has been a major issue back through the ASP.Net Web Forms era.Perhaps your test should focus on the HelpPageBusinessService.
If all else fails perhaps pass a helper class via dependency injection to your controller, that adds the header or mock with a mocking framework.
Upvotes: 1