Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moq Mocking and tracking Session values

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?

like image 418
sean Avatar asked Oct 29 '09 09:10

sean


3 Answers

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);
        });
like image 100
sean Avatar answered Oct 27 '22 00:10

sean


Moq's Setup methods do not work with indexed properties that have string indexes. See here: How to MOQ an Indexed property

like image 2
Konamiman Avatar answered Oct 27 '22 01:10

Konamiman


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);
like image 1
stoj Avatar answered Oct 27 '22 00:10

stoj