3

我试图设置会话变量以运行一些单元测试没有成功。当我尝试设置会话变量时,我不断收到“System.NullReferenceException:对象引用未设置为对象的实例”的错误。

这是我正在构建的测试:

[TestMethod]
public void MyMethod()
{
  //Arrange
  int id = 12345;
  string action = "A";
  string comment = "";
  string user = "user";
  var controller = new MyController();

  //Act
  controller.Session["altUser"] = user;
  var result = controller.Process(id, action, comment);

  //Assert
  Assert.IsNotNull(result);     
}

这是我的控制器:

[Authorize]
public class MyController : Controller
{
  public ActionResult Process(int id, string action, string comment)
  {
    string userId = Session["altUser"].ToString();
    //some other stuff that evaluates ID, Action, and Comment
  }
}

但是,当我运行应用程序本身时,没有错误并且应用程序可以正常运行。我确实明白,通过测试驱动开发,测试应该为实现铺平道路。我正在尝试对已经完成的应用程序进行单元测试的一些练习。如果可能的话,由于应用程序工作正常,我想避免对我的实现进行任何更改,而只是编写一个单元测试来支持我已经知道的内容。

4

3 回答 3

8

控制器从 中获取会话,该会话HttpContext在您的单元测试中不存在,这就是它失败的原因。

但是,您也可以模拟HttpContext并在其中放置模拟会话。

像这样的东西可能会起作用(使用 moq 作为 Mocking 框架)

    var mockControllerContext = new Mock<ControllerContext>();
    var mockSession = new Mock<HttpSessionStateBase>();
    mockSession.SetupGet(s => s["altUser"]).Returns("user");
    mockControllerContext.Setup(p => p.HttpContext.Session).Returns(mockSession.Object);

    var controller = new MyController();
    controller.ControllerContext = mockControllerContext.Object;

您显然需要用您实际想要输出的详细信息填充模拟对象。

HttpSessionStateBase您还可以从并HttpContextBase使用它们而不是真正的会话派生自己的类。

于 2013-03-11T21:57:50.873 回答
2

没有勺子,呃,会话——当您执行单元测试时,ASP.NET 运行程序既没有初始化也没有运行。您应该分解Session代码外部的所有依赖项,并使单元测试所需的类和方法独立于 ASP.NET 的运行时功能。

于 2013-03-11T21:57:05.620 回答
0

当您运行单元测试时,您不是通过 Web 服务器运行程序,因此无法访问任何 HttpContext 或 ASP.NET 会话,而当您在 VS 中通过调试运行程序时,您使用的是内置 Visual Studio Web 服务器,使程序能够使用会话。

是一篇带您了解 ASP.NET 会话及其工作原理的文章。

于 2013-03-11T21:57:03.213 回答