Unit Testing Controller Actions that call IsAjaxRequest()
Some of my controller actions need to respond wi开发者_运维问答th 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;
}
}
精彩评论