Tengo una acción de controlador que redirige automáticamente a una nueva página si el usuario ya ha iniciado sesión (User.Identity.IsAuthenticated
). ¿Cuál es la mejor manera de escribir una prueba unitaria para este escenario para garantizar que la redirección tenga lugar?¿Cómo pruebo la unidad de una acción de controlador que utiliza su controlador. Variable de usuario?
¿Cómo pruebo la unidad de una acción de controlador que utiliza su controlador. Variable de usuario?
Respuesta
He estado utilizando los siguientes Mocks con Moq para permitir configurar varias condiciones en las pruebas de mi unidad. En primer lugar, la maqueta HttpContextBase:
public static Mock<HttpContextBase> GetHttpContextMock(bool isLoggedIn)
{
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>();
var principal = AuthenticationAndAuthorization.GetPrincipleMock(isLoggedIn);
context.SetupGet(c => c.Request).Returns(request.Object);
context.SetupGet(c => c.Response).Returns(response.Object);
context.SetupGet(c => c.Session).Returns(session.Object);
context.SetupGet(c => c.Server).Returns(server.Object);
context.SetupGet(c => c.User).Returns(principal.Object);
return context;
}
Cada propiedad que podrían proporcionar una Mock útil se estableció aquí. De esa manera, si tengo que añadir algo así como un referente, que sólo puede utilizar:
Mock.Get(controller.Request).Setup(s => s.UrlReferrer).Returns(new Uri("http://blah.com/");
El método "GetPrincipleMock" es lo que establece el usuario. Se ve así:
public static Mock<IPrincipal> GetPrincipleMock(bool isLoggedIn)
{
var mock = new Mock<IPrincipal>();
mock.SetupGet(i => i.Identity).Returns(GetIdentityMock(isLoggedIn).Object);
mock.Setup(i => i.IsInRole(It.IsAny<string>())).Returns(false);
return mock;
}
public static Mock<IIdentity> GetIdentityMock(bool isLoggedIn)
{
var mock = new Mock<IIdentity>();
mock.SetupGet(i => i.AuthenticationType).Returns(isLoggedIn ? "Mock Identity" : null);
mock.SetupGet(i => i.IsAuthenticated).Returns(isLoggedIn);
mock.SetupGet(i => i.Name).Returns(isLoggedIn ? "testuser" : null);
return mock;
}
Ahora, mis configuraciones de controlador en las pruebas de tener este aspecto:
var controller = new ProductController();
var httpContext = GetHttpContextMock(true); //logged in, set to false to not be logged in
ControllerContext controllerContext = new ControllerContext(httpContext.Object, new RouteData(), controller);
controller.ControllerContext = controllerContext;
Es un poco de configuración detallado, pero una vez que tenga todo en su lugar, poniendo a prueba una variedad de las condiciones se vuelve mucho más fácil.
No es lo más simple de hacer, pero se puede hacer. La propiedad User simplemente delega a Controller.HttpContext.User. Ambas son propiedades de solo lectura no virtuales, por lo que no puede hacer nada al respecto. Sin embargo, Controller.HttpContext delega a ControllerBase.ControllerContext que es una propiedad de escritura.
Por lo tanto, puede asignar una prueba doble HttpContextBase a Controller.ControllerContext antes de ejercitar su sistema bajo prueba (SUT). El uso Moq, se vería algo como esto:
var user = new GenericPrincipal(new GenericIdentity(string.Empty), null);
var httpCtxStub = new Mock<HttpContextBase>();
httpCtxStub.SetupGet(ctx => ctx.User).Returns(user);
var controllerCtx = new ControllerContext();
controllerCtx.HttpContext = httpCtxStub.Object;
sut.ControllerContext = controllerCtx;
luego llamar a su acción y verificar que el resultado devuelto es un RedirectResult.
Esta prueba utiliza el conocimiento implícito de que cuando se crea una identidad genérica con un nombre vacío, devolverá falso para IsAuthenticated. Podría considerar hacer la prueba más explícita utilizando en su lugar un Mock<IIdentity>
.
- 1. controlador de Acción Prueba que utiliza User.Identity.Name
- 2. ¿Cómo pruebo la asignación de una variable de instancia en la nueva acción de mi controlador con rspec?
- 3. ¿Cómo pruebo la unidad de objetos heredados?
- 4. ¿Cómo hacer que CakePHP redirija a una acción/controlador diferente?
- 5. ¿Cómo probar la unidad de una acción de controlador MVC que depende de la autenticación en C#?
- 6. Render acción del controlador desde otro controlador
- 7. ¿Cómo pruebo la unidad de un finalizador?
- 8. ¿Cuál es la forma correcta de ejecutar una acción de controlador desde otra acción de controlador sin una redirección HTTP?
- 9. ¿Cómo pruebo el método OnActionExecuting de mi controlador asp.net-mvc?
- 10. Controlador MVC3 Accesibilidad variable
- 11. Redirigir a la acción en otro controlador
- 12. ¿Cómo redirecciono al usuario a otra acción del controlador desde un filtro de acción ASP.MVC 3?
- 13. backgroundworker bloqueando la acción del controlador MVC
- 14. Ejecutar código antes de la acción del controlador
- 15. ¿Cómo pruebo la unidad para EXC_BAD_ACCESS?
- 16. Devolución de una redirección 301 desde una acción de controlador
- 17. ¿Cómo debería ser una acción de controlador si solo redirige?
- 18. Unidad probando un método de controlador?
- 19. prueba de la unidad de acción del controlador yü sin selenio
- 20. Uso de jQuery para llamar a una acción de controlador
- 21. ¿Cómo puedo probar la unidad de un controlador Symfony2?
- 22. ¿Cómo pruebo la unidad de una tarea personalizada?
- 23. Buscando dirección en la unidad probando una extensión de controlador que rinde una vista parcial
- 24. ¿Cómo compruebo la unidad de un método de controlador que tiene aplicado el atributo [Autorizar]?
- 25. Rieles: Cómo determinar controlador/acción en vista
- 26. Perfil de una acción de controlador de rieles
- 27. Cómo llegar controlador y nombre de la acción en ZF2
- 28. ASP.NET MVC enviando datos JSON a una acción de controlador
- 29. Redirigir a la acción en otro controlador
- 30. Rieles: nombre de la acción del controlador en la cadena
Perfecto. La respuesta sigue siendo relevante. + 1 – joshmcode