【问题标题】:Moq Mocking and tracking Session valuesMoq 模拟和跟踪会话值
【发布时间】:2009-10-29 09:57:37
【问题描述】:

我在使用 Moq 模拟返回会话值集时遇到问题。使用以下

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;
        });
  }
}

当我尝试使用外部获取值时

var th = new TestHelpers();
HttpContextBase httpContext = th.FakeHttpContext();

做一些设置 Session["id"]

var sessionid = httpContext.Session["id"];

sessionid 结果是-1。但我可以使用

获取设置的会话值
th.sessionValue

怎么了?我不能简单地通过起订量返回设定值吗?

【问题讨论】:

    标签: c# asp.net-mvc mocking moq


    【解决方案1】:

    我需要停止回答我自己的问题。原来我需要像这样再次模拟 Session["id"] ...

    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 的Setup 方法不适用于具有字符串索引的索引属性。见这里:How to MOQ an Indexed property

    【讨论】:

    • 如果它不起作用,那么 Session["id"] 不应该返回 null 而不是 -1?
    • 另外,您链接到的问题的答案似乎表明它有效?
    【解决方案3】:

    这是因为您返回的是按值传递的 getter 中的值。因此,每次调用 getter 时,都会返回相同的值。

    将 Returns() 更改为使用委托,以便每次都对其进行评估。这样你每次都会得到正确的值:)

    比在 SetupSet 中嵌入 SetupGet 更容易。

    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】:

      我只是花了很长时间试图找出使用 moq 的最简单方法,下面是我的代码的副本,它实际上对我有用:

      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;
      

      希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 2018-02-05
        • 1970-01-01
        • 1970-01-01
        • 2013-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-19
        • 1970-01-01
        相关资源
        最近更新 更多