Bit of a noob with testing so please bear with me,
I have a controller that returns a JsonResult that contains a string calculated by Url.Action like this:
public ActionResult GetResult(SomeModel model)
{
if (ModelState.IsValid)
{
return Json(new { redirectTo = Url.Action("Index", "Profile") });
}
}
And the application works just fine when I use that result using jQuery.
However during my unit testing I have issues because when I test the content of the Json string the redirectTo value appears to be "null" even though it's not null in the application itself.
My test method looks a bit like this:
[Test]
public void GetResult_Success()
{
var result = controller.GetResult(new SomeModel());
Assert.IsNotNull(result);
Assert.IsInstanceOf<JsonResult>(result);
var jsonResult = result as JsonResult;
var jsonObject = JsonConvert.DeserializeAnonymousType(new JavaScriptSerializer().Serialize(jsonResult.Data), new
{
redirectTo = string.Empty
});
Assert.AreEqual("Profile/Index", jsonObject.redirectTo);
}
This fails because jsonObject.redirectTo is null. If in my controller I change Url.Action into "Profile/Index" the test passes. However Url.Action("Index", "Profile") fails because it becomes null only in unit testing.
If I try to set up the route values in the Context setup for the tests it complains that they are already registered. I'm using Moq. Any idea what I need to set up? Many thanks in advance
The answer can be found at this link
Code copied for more permanence:
public static void SetupWithHttpContextAndUrlHelper(this Controller controller)
{
var routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);
//setup request
var requestContextMock = new Mock<HttpRequestBase>();
requestContextMock.Setup(r => r.AppRelativeCurrentExecutionFilePath).Returns("/");
requestContextMock.Setup(r => r.ApplicationPath).Returns("/");
//setup response
var responseMock = new Mock<HttpResponseBase>();
responseMock.Setup(s => s.ApplyAppPathModifier(It.IsAny<string>())).Returns<string>(s => s);
//setup context with request and response
var httpContextMock = new Mock<HttpContextBase>();
httpContextMock.Setup(h => h.Request).Returns(requestContextMock.Object);
httpContextMock.Setup(h => h.Response).Returns(responseMock.Object);
controller.ControllerContext = new ControllerContext(httpContextMock.Object, new RouteData(), controller);
controller.Url = new UrlHelper(new RequestContext(httpContextMock.Object, new RouteData()), routes);
}