2011-08-08 53 views
4

我正在对我的控制器进行单元测试。单元测试控制器MVC3中的会话变量

在我的控制器方法我设置会话变量之一:

public void Index(){ 
     Session["foo"] = "bar"; 

     return View(); 
} 

我怎么能单元测试呢?问题是测试时会话属性为空。注入是不可能的,因为会话属性是只读的。

[TestMethod] 
public void TestIndex() 
    // When 
    _controller.Index(); 

    // Then 
    Assert.AreEqual("bar", _controller.Session["foo"]) 

回答

7

链接个人而言,我喜欢使用它嘲笑所有的HTTP管道MvcContrib TestHelper

[TestMethod] 
public void HomeController_Index_Action_Should_Store_Bar_In_Session() 
{ 
    // arrange 
    var sut = new HomeController(); 
    new TestControllerBuilder().InitializeController(sut); 

    // act 
    sut.Index(); 

    // assert 
    Assert.AreEqual("bar", (string)sut.Session["foo"]); 
} 
+0

关于ASP.NET MVC5?正如我可以读MvcContrib TestHelper系统要求说FOR USE ASP.Net MVC 1或 ASP.Net MVC 2或 ASP.Net MVC 3 促进发展 的.Net 3.5 SP1或 .NET 4.0 –

+0

我也对克拉克肯特的问题感兴趣。 MvcContrib似乎没有更新一段时间了。我可以安全地使用MVC 5项目中的TestHelper名称空间中的类吗? – SoonDead

2

我总是建议在另一个对象中翘曲会话对象。这不仅可以让您更轻松地进行测试,而且还可以安全地访问会话类型,因此很容易在一个地方的某个地方键入会话密钥名称,然后将该错误追踪数小时。 的对象有领域

public Foo{ 
get{return Session["Foo"];} 
set{Session["Foo"]=value;} 
} 

一旦你测试你可以模拟会话类与虚拟,只有保持状态进行测试。 我通常处理的方式是依赖注入。如何设置这是一个漫长的考验。这里是一个办法 http://weblogs.asp.net/shijuvarghese/archive/2011/01/21/dependency-injection-in-asp-net-mvc-3-using-dependencyresolver-and-controlleractivator.aspx

+0

你能举个例子吗? – Tobias

3

这是我使用单元测试友好会话缓存。通过检查HttpContext.Current为null,您可以通过为nunit测试传递缓存并仍然允许程序正常运行。

这是最简单的解决方案,无需在项目中进行大量的代码更改。

internal class SessionCache 
{ 
    public static void Store(string key, object val) { 
     if (HttpContext.Current != null) { 
      HttpContext.Current.Session[key] = val; 
     } 
    } 

    public static object Retrieve(string key) { 
     if (HttpContext.Current != null) { 
      return HttpContext.Current.Session[key]; 
     } 

     return null; 
    } 
}