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?
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);
});
Moq's Setup
methods do not work with indexed properties that have string indexes. See here: How to MOQ an Indexed property
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With