2009-10-29 106 views
5

我有問題返回使用Moq嘲笑的會話值集。使用下面的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(); 

做一些東西,設置會話值[ 「ID」]

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

的SessionID真可謂爲-1。但我可以使用

th.sessionValue 

怎麼了?我不能簡單地通過Moq返回設定值嗎?

回答

11

我需要停止回答我自己的問題。事實證明,我需要再次嘲笑會話[「身份證」]是這樣的...

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

這對我沒有用:@Konamimam似乎是正確的,.Callback不會被解僱。正確的方法似乎在這裏:http://stackoverflow.com/a/2921695/213609 – 2013-05-10 15:17:56

2

Moq的Setup方法不適用於具有字符串索引的索引屬性。看到這裏:How to MOQ an Indexed property

+0

如果它不起作用,那麼應該不會Session [「id」]返回null而不是-1? – sean 2009-10-29 12:33:26

+0

另外,您鏈接的問題的答案似乎表明它的工作原理? – 2009-10-29 16:01:14

1

這是因爲你在回國這是按值傳遞,吸附劑中的價值。所以每次調用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); 
1

我只花了很長時間試圖找出與起訂量做到這一點最簡單的方法,下面是我的代碼複製過去,實際上爲我工作:

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; 

希望這有助於!