Moq Mocking and tracking Session values

♀尐吖头ヾ 提交于 2020-01-21 07:20:28

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!