asp.net-mvc - test - pruebas unitarias c# mvc
ASP.NET MVC: Controladores de pruebas unitarias que usan UrlHelper (5)
Aquí está una de mis pruebas (xUnit + Moq) solo para casos similares (usando Url.RouteUrl en el controlador)
Espero que esto ayude:
var routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute));
request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection());
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
response.Setup(x => x.ApplyAppPathModifier("/post1")).Returns("http://localhost/post1");
var context = new Mock<HttpContextBase>(MockBehavior.Strict);
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
var controller = new LinkbackController(dbF.Object);
controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
controller.Url = new UrlHelper(new RequestContext(context.Object, new RouteData()), routes);
Una de las acciones de mis controladores, una que se llama en una solicitud de Ajax, es devolver una URL al lado del cliente para que pueda hacer una redirección. Estoy usando Url.RouteUrl(..)
y durante las pruebas de mi unidad esto falla ya que el parámetro Controller.Url
no se llena previamente.
Intenté muchas cosas, entre otras, UrlHelper
(que falló), crear manualmente un UrlHelper
con un RequestContext
que tiene una HttpContextBase
(que falló en una llamada a RouteCollection.GetUrlWithApplicationPath
).
He buscado en Google pero no he encontrado prácticamente nada sobre el tema. ¿Estoy haciendo algo increíblemente estúpido usando Url.RouteUrl
en mi acción de controlador? hay una manera mas facil?
Para empeorar las cosas, me gustaría poder probar la URL devuelta en mi prueba de unidad, de hecho, solo estoy interesado en saber que está redirigiendo a la ruta correcta, pero dado que estoy devolviendo una URL en lugar de una ruta, me gustaría controlar la URL que se resuelve (por ejemplo, mediante el uso de un RouteCollection
), pero estaré encantado de comenzar mi prueba de aprobación.
Construyendo la respuesta de @ eu-ge-ne que me ayudó mucho:
Tuve un ActionResult que hizo una redirección y también tuve una llamada a UpdateModel con un parámetro FormCollection. Para que UpdateModel () funcione, tuve que agregar esto a mi Mocking HttpRequestBase:
FormCollection collection = new FormCollection();
collection["KeyName"] = "KeyValue";
request.Setup(x => x.Form).Returns(collection);
request.Setup(x => x.QueryString).Returns(new NameValueCollection());
Para probar que la URL redirigida era correcta, puede hacer lo siguiente:
RedirectResult result = controller.ActionName(modelToSubmit, collection) as RedirectResult;
Assert.AreEqual("/Expected/URL", result.Url);
Esta publicación puede ser útil si quieres burlar la clase HttpContextBase.
http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx
Una implementación modificada de eu-ge-ne. Éste devuelve un enlace generado en función de las rutas definidas en la aplicación. El ejemplo de eu-ge-ne siempre devuelve una respuesta fija. El siguiente enfoque le permitirá probar que la acción correcta / controlador y la información de ruta se transfieren al UrlHelper, que es lo que desea si está probando la llamada al UrlHelper.
var context = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
var response = new Mock<HttpResponseBase>();
var session = new Mock<HttpSessionStateBase>();
var server = new Mock<HttpServerUtilityBase>();
context.Setup(ctx => ctx.Request).Returns(request.Object);
context.Setup(ctx => ctx.Response).Returns(response.Object);
context.Setup(ctx => ctx.Session).Returns(session.Object);
context.Setup(ctx => ctx.Server).Returns(server.Object);
request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost/a", UriKind.Absolute));
request.SetupGet(x => x.ServerVariables).Returns(new NameValueCollection());
response.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())).Returns<string>(x => x);
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
var routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);
var helper = new UrlHelper(new RequestContext(context.Object, new RouteData()), routes);
http://kbochevski.blogspot.com/2010/06/unit-testing-mvcnet.html explica cómo cubrir todas las capas con pruebas unitarias. Utiliza Rhino y MVC.Contrib para las pruebas de los controladores. El código fuente en google puede ser de gran ayuda.