Moq模拟和跟踪会话值

时间:2009-10-29 09:57:37

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

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

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

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

4 个答案:

答案 0 :(得分:11)

我需要停止回答我自己的问题。事实证明,我需要再次模仿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);
        });

答案 1 :(得分:2)

Moq的Setup方法不适用于具有字符串索引的索引属性。见这里:How to MOQ an Indexed property

答案 2 :(得分:1)

这是因为你正在返回通过值传递的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);

答案 3 :(得分:1)

我花了很长时间试图找出用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;

希望这有帮助!