Some of my controller actions need to respond with different ViewResults depending whether or not they were called by an AJAX request. Currently, I'm using the IsAjaxRequest()
method to check for this. When this method is called during a unit test, it throws an ArgumentNullException
because the HTTP context is missing.
Is there a way to mock/fake this call? Or is this a sign I should be checking for an AJAX request another way?
Would it help if you provide a Test Double for the HTTP Context?
This can be done like this:
var httpCtxStub = new Mock<HttpContextBase>();
var controllerCtx = new ControllerContext();
controllerCtx.HttpContext = httpCtxStub.Object;
sut.ControllerContext = controllerCtx;
where sut
represents the System Under Test (SUT), i.e. the Controller you wish to test.
This example uses Moq.
Using moq
library in MVC test projects
[TestClass]
public class HomeControllerTest
{
[TestMethod]
public void Index()
{
// Arrange
HomeController controller = new HomeController();
controller.injectContext();
// controller.injectContext(ajaxRequest: true);
// Act
ViewResult result = controller.Index() as ViewResult;
// Assert
Assert.IsNotNull(result);
}
}
public static class MvcTestExtensions
{
public static void injectContext(this ControllerBase controller, bool ajaxRequest = false)
{
var fakeContext = new Mock<ControllerContext>();
fakeContext.Setup(r => r.HttpContext.Request["X-Requested-With"])
.Returns(ajaxRequest ? "XMLHttpRequest" : "");
controller.ControllerContext = fakeContext.Object;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With