在MVC3中,单元测试控制器会话变量

4

我正在对我的控制器进行单元测试。

在我的一个控制器方法中,我正在设置Session变量:

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

      return View();
 }

我该如何对此进行单元测试?问题在于在测试时Session属性为空。注入不可能,因为Session属性是只读的。

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

     // Then
     Assert.AreEqual("bar", _controller.Session["foo"])
3个回答

7
个人而言,我喜欢使用MvcContrib TestHelper,它可以模拟整个HTTP管道:
[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"]);
}

ASP.NET MVC5怎么样?根据我所读到的MvcContrib TestHelper系统要求,适用于:ASP.Net MVC 1 或 ASP.Net MVC 2 或 ASP.Net MVC 3开发方面需要:.Net 3.5 SP1 或 .Net 4.0 - NoWar
我也对Clark Kent的问题感兴趣。MvcContrib似乎已经有一段时间没有更新了。我能否在MVC 5项目中安全使用TestHelper命名空间中的类? - vinczemarton

3

这是我用于单元测试友好的会话缓存。通过检查HttpContext.Current是否为空,您可以绕过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;
    }
}

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

你能发一个例子吗? - Tobias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接