问题
I'm having problems returning a Session value set from mocking using Moq. Using the following
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;
});
}
}
When I try to obtain the value outside using
var th = new TestHelpers();
HttpContextBase httpContext = th.FakeHttpContext();
do some stuff that sets Session["id"]
var sessionid = httpContext.Session["id"];
sessionid turns out to be -1. But I can obtain the set session value using
th.sessionValue
What's wrong? Can't I simply return the set value via Moq?
回答1:
I need to stop answering my own questions. It turns out that I needed to mock Session["id"] again like so ...
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);
});
回答2:
Moq's Setup
methods do not work with indexed properties that have string indexes. See here: How to MOQ an Indexed property
回答3:
It's because you're returning the value in the getter which was passed by value. So everytime you invoke the getter, you get the same value returned.
Change the Returns() to use a delegate so it is evaluated every time. That way you will get the correct value every time :)
Much easier on the eye than a SetupGet embedded inside a 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);
回答4:
I just spent long time trying to figure out the easiest way to do it with moq, below is a copy past of my code that actually worked for me :
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;
hope this helps!
来源:https://stackoverflow.com/questions/1642631/moq-mocking-and-tracking-session-values