I want to test an action in my controller that use a controllerContext as a parameter to generate a pdf document based on a 3th part library "Rotativa".
Here is the implementation of the action (function) :
public ActionResult DetailsPrint(int? id)
{
var a = new ViewAsPdf();
a.ViewName = "../Ops/_2A1/Details";
a.Model =UnitOfWork._2A1s.Get(id.Value);
var pdfBytes = a.BuildPdf(ControllerContext);
// return ActionResult
MemoryStream ms = new MemoryStream(pdfBytes);
return new FileStreamResult(ms, "application/pdf");
}
And here is how I'm trying to get a unit test works :
Constructor
public _2A1ControllerTest() { _mockRepository = new Mock<I2A1Repository>(); var mockUoW = new Mock<IUnitOfWork>(); _mockHttpContext = new Mock<HttpContextBase>(); _mockRequest = new Mock<HttpRequestBase>(); _mockDisplayModeContext = new Mock<IDisplayMode>(); mockUoW.SetupGet(u => u._2A1s).Returns(_mockRepository.Object); _mockHttpContext.SetupGet(x => x.Request).Returns(_mockRequest.Object); _controller = new _2A1Controller(mockUoW.Object); _controller.MockCurrentUser("test.admin"); _controller.ControllerContext = new ControllerContext(_mockHttpContext.Object, new System.Web.Routing.RouteData(), _controller); }Test Function
[TestMethod] public void DetailsPrint_shouldPrint() { var result = _controller.DetailsPrint(1) as ActionResult; result.Should().BeOfType<ActionResult>(); }
Test Name: DetailsPrint_shouldPrint Test FullName: OPSReviewTest._2A1ControllerTest.DetailsPrint_shouldPrint Test Source: C:\inetpub\wwwroot\OpsReview\OPSReviewTest\Controllers\Api_2A1ControllerTest.cs : line 46 Test Outcome: Failed Test Duration: 0:04:39,3039007 Result StackTrace:
at System.Web.WebPages.DisplayModeProvider.GetDisplayMode(HttpContextBase context) at System.Web.Mvc.ControllerContext.get_DisplayMode() Result Message: Test method OPSReviewTest._2A1ControllerTest.DetailsPrint_shouldPrint threw exception: System.NullReferenceException: Object reference not set to an instance of an object.
Any help or suggestion, Thanks.

You are trying to unit test code you don't own? (Shame, [Bell tolls], shame...)
If the goal was to test the controller action flow in isolation then it is advised to abstract out the 3rd party PDF generation so that it can be mocked for easier testability.
The abstraction can now be injected into the controller to be used per request action as needed.
And now the unit test can safely mock the 3rd party functionality
Assuming the use of FluentAssertions, the test method should look like this (Pun intended :))
Finally, don't forget to register the interface and its implementation with your DI container in production.