我在这里阅读了一些答案:测试视图和控制器,以及模拟,但我仍然无法弄清楚如何测试读取和设置Session值(或任何其他基于上下文的变量)的ASP.NET MVC控制器.如何为我的测试方法提供(会话)上下文?嘲笑答案?有人有例子吗?基本上,我想在调用控制器方法并让控制器使用该会话之前伪造一个会话.有任何想法吗?
查看Stephen Walther关于伪造控制器上下文的帖子:
ASP.NET MVC技巧#12 - 伪造控制器上下文
[TestMethod] public void TestSessionState() { // Create controller var controller = new HomeController(); // Create fake Controller Context var sessionItems = new SessionStateItemCollection(); sessionItems["item1"] = "wow!"; controller.ControllerContext = new FakeControllerContext(controller, sessionItems); var result = controller.TestSession() as ViewResult; // Assert Assert.AreEqual("wow!", result.ViewData["item1"]); // Assert Assert.AreEqual("cool!", controller.HttpContext.Session["item2"]); }
ASP.NET MVC框架不是非常模拟友好的(或者更确切地说,需要太多的设置才能正确地进行模拟,并且在测试时会导致太多摩擦,恕我直言),因为它使用了抽象基类而不是接口.我们很幸运为每个请求和基于会话的存储编写抽象.我们保持这些抽象非常轻,然后我们的控制器依赖于每个请求或每个会话存储的抽象.
例如,这是我们如何管理表单auth的东西.我们有一个ISecurityContext:
public interface ISecurityContext { bool IsAuthenticated { get; } IIdentity CurrentIdentity { get; } IPrincipal CurrentUser { get; set; } }
具体实现如下:
public class SecurityContext : ISecurityContext { private readonly HttpContext _context; public SecurityContext() { _context = HttpContext.Current; } public bool IsAuthenticated { get { return _context.Request.IsAuthenticated; } } public IIdentity CurrentIdentity { get { return _context.User.Identity; } } public IPrincipal CurrentUser { get { return _context.User; } set { _context.User = value; } } }
使用MVC RC 1,ControllerContext包装HttpContext并将其作为属性公开.这使得模拟更容易.要使用Moq模拟会话变量,请执行以下操作:
var controller = new HomeController(); var context = MockRepository.GenerateStub(); context.Expect(x => x.HttpContext.Session["MyKey"]).Return("MyValue"); controller.ControllerContext = context;
有关详细信息,请参阅Scott Gu的帖子.
我觉得嘲笑相当容易.下面是使用moq模拟httpContextbase(包含请求,会话和响应对象)的示例.
[TestMethod] public void HowTo_CheckSession_With_TennisApp() { var request = new Mock(); request.Expect(r => r.HttpMethod).Returns("GET"); var httpContext = new Mock (); var session = new Mock (); httpContext.Expect(c => c.Request).Returns(request.Object); httpContext.Expect(c => c.Session).Returns(session.Object); session.Expect(c => c.Add("test", "something here")); var playerController = new NewPlayerSignupController(); memberController.ControllerContext = new ControllerContext(new RequestContext(httpContext.Object, new RouteData()), playerController); session.VerifyAll(); // function is trying to add the desired item to the session in the constructor //TODO: Add Assertions }
希望有所帮助.