Moq Mocking y seguimiento de valores de sesión
-
10-07-2019 - |
Pregunta
Tengo problemas para devolver un conjunto de valores de sesión de burlarse de Moq. Usando lo siguiente
public class TestHelpers
{
public long sessionValue = -1;
public HttpContextBase FakeHttpContext()
{
var httpContext = new Mock<HttpContextBase>();
var session = new Mock<HttpSessionStateBase>();
httpContext.Setup(x => x.Session).Returns(session.Object);
httpContext.SetupGet(x => x.Session["id"]).Returns(sessionValue);
httpContext.SetupSet(x => x.Session["id"] = It.IsAny<long>())
.Callback((string name, object val) =>
{
sessionValue = (long)val;
});
}
}
Cuando intento obtener el valor fuera usando
var th = new TestHelpers();
HttpContextBase httpContext = th.FakeHttpContext();
hacer algunas cosas que configuran la sesión [" id "]
var sessionid = httpContext.Session["id"];
sessionid resulta ser -1. Pero puedo obtener el valor de sesión establecido usando
th.sessionValue
¿Qué pasa? ¿No puedo simplemente devolver el valor establecido a través de Moq?
Solución
Necesito dejar de responder mis propias preguntas. Resulta que necesitaba burlarme de la sesión [" id "] nuevamente así ...
httpContext.SetupSet(x => x.Session["id"] = It.IsAny<long>())
.Callback((string name, object val) =>
{
sessionValue = (long)val;
httpContext.SetupGet(x => x.Session["id"]).Returns(sessionValue);
});
Otros consejos
métodos Setup
de Moq no funcionan con propiedades indexadas que tienen índices de cadena. Ver aquí: Cómo MOQ una propiedad indexada
Es porque está devolviendo el valor en el captador que se pasó por valor. Entonces, cada vez que invocas al getter, obtienes el mismo valor devuelto.
Cambie Returns () para usar un delegado para que se evalúe cada vez. De esa manera obtendrá el valor correcto cada vez :)
Mucho más fácil a la vista que un SetupGet incrustado dentro de un SetupSet.
httpContext.SetupSet(x => x.Session["id"] = It.IsAny<long>())
.Callback((string name, object val) => sessionValue = (long)val);
httpContext.SetupGet(x => x.Session["id"]).Returns(() => sessionValue);
Acabo de pasar mucho tiempo tratando de descubrir la forma más fácil de hacerlo con moq, a continuación hay una copia del código que realmente funcionó para mí:
var _adminctrl = new Moq.Mock<AdminController>(); //AdminController is my MVC controller
var mock = new Mock<ControllerContext>();
mock.Object.Controller = _adminctrl.Object;
mock.Setup(p => p.HttpContext.Session["UserInfoKey"]).Returns(new ViewModel());
//here is the catch, attaching the ControllerContext to your controller
_adminctrl.Object.ControllerContext = mock.Object;
¡espero que esto ayude!