如何测试ASP.NET控制器在Session使用下的表现?

2026-04-30 14:339阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计706个文字,预计阅读时间需要3分钟。

如何测试ASP.NET控制器在Session使用下的表现?

如何准备ASP.NET MVC控制器使用Session同时是可测试的,本质上不使用Session而是使用一些Session抽象?我目前正在使用Ninject,因此您的示例可以基于此。

问题在于Session对象在控制器中的生命周期管理。在控制器中直接使用Session可能会导致难以测试,因为Session通常与特定用户的会话绑定,而测试通常需要模拟用户会话。

以下是使用Ninject和Session抽象来改进控制器测试性的一个示例:

csharppublic class MyController : Controller{ private readonly IMyService _myService;

public MyController(IMyService myService) { _myService=myService; }

public ActionResult MyAction() { var sessionKey=MySessionKey; var sessionObject=HttpContext.Session[sessionKey];

if (sessionObject==null) { sessionObject=_myService.CreateObject(); HttpContext.Session[sessionKey]=sessionObject; }

return View(sessionObject); }}

public interface IMyService{ object CreateObject();}

public class MyService : IMyService{ public object CreateObject() { return new object(); }}

在这个示例中,`IMyService` 接口定义了创建Session对象的方法。`MyService` 类实现了这个接口,并在`CreateObject`方法中创建了一个新的对象。`MyController` 通过构造函数注入`IMyService`,从而允许在测试中替换它。

为了测试`MyController`,可以创建一个模拟的`IMyService`实现,该实现返回一个特定的对象,而不是创建一个新的对象。这样,你就可以控制测试中的Session对象。

如何测试ASP.NET控制器在Session使用下的表现?

csharp[TestClass]public class MyControllerTests{ [TestMethod] public void MyAction_ReturnsCorrectObject() { // Arrange var mockService=new Mock(); mockService.Setup(m=> m.CreateObject()).Returns(new object()); var controller=new MyController(mockService.Object);

// Act var result=controller.MyAction() as ViewResult;

// Assert Assert.IsNotNull(result); var model=result.Model; Assert.IsInstanceOfType(model, typeof(object)); }}

通过这种方式,你可以避免直接在控制器中使用Session,而是通过依赖注入和抽象来管理会话状态,从而提高代码的可测试性。

如何准备ASP.NET MVC控制器使用Session同时是可测试的,所以本质上不使用Session而是使用一些Session抽象?我正在使用Ninject,因此您的示例可以基于此.

问题是Session对象在控制器中始终不可用(如在ctor中),但我需要在应用程序启动时将某些内容存储到Session(global.asax.cs也无法访问Session).

如果您希望您的类可以测试,请不要在那里使用不可测试的(外部)组件.当你试图模仿它们时,你只需要解决这个糟糕的设计.改为重新设计控制器.类不应该依赖外部/全局对象.这就是使用IoC的原因之一.

您可以通过两种方法将实施/基础架构详细信息与控制器分开:

>次要抽象

public interface ISession { string GetValue(string name); void SetValue(string name, string value); }

>域抽象.

public interface IStateData { bool IsPresent { get; } int MyDomainMeaningfulVariable { get; set; } }

在后一种情况下,接口会在会话中添加语义 – 强类型,命名良好的属性.这与使用NHibernate域实体而不是sqlreader [“DB_COLUMN_NAME”]一样.

然后,当然,将接口的HTTP实现(例如,使用HttpContext.Current)注入控制器.

模型粘合剂也是一种很好的方法,就像动作过滤器一样.他们是not just for form data.

本文共计706个文字,预计阅读时间需要3分钟。

如何测试ASP.NET控制器在Session使用下的表现?

如何准备ASP.NET MVC控制器使用Session同时是可测试的,本质上不使用Session而是使用一些Session抽象?我目前正在使用Ninject,因此您的示例可以基于此。

问题在于Session对象在控制器中的生命周期管理。在控制器中直接使用Session可能会导致难以测试,因为Session通常与特定用户的会话绑定,而测试通常需要模拟用户会话。

以下是使用Ninject和Session抽象来改进控制器测试性的一个示例:

csharppublic class MyController : Controller{ private readonly IMyService _myService;

public MyController(IMyService myService) { _myService=myService; }

public ActionResult MyAction() { var sessionKey=MySessionKey; var sessionObject=HttpContext.Session[sessionKey];

if (sessionObject==null) { sessionObject=_myService.CreateObject(); HttpContext.Session[sessionKey]=sessionObject; }

return View(sessionObject); }}

public interface IMyService{ object CreateObject();}

public class MyService : IMyService{ public object CreateObject() { return new object(); }}

在这个示例中,`IMyService` 接口定义了创建Session对象的方法。`MyService` 类实现了这个接口,并在`CreateObject`方法中创建了一个新的对象。`MyController` 通过构造函数注入`IMyService`,从而允许在测试中替换它。

为了测试`MyController`,可以创建一个模拟的`IMyService`实现,该实现返回一个特定的对象,而不是创建一个新的对象。这样,你就可以控制测试中的Session对象。

如何测试ASP.NET控制器在Session使用下的表现?

csharp[TestClass]public class MyControllerTests{ [TestMethod] public void MyAction_ReturnsCorrectObject() { // Arrange var mockService=new Mock(); mockService.Setup(m=> m.CreateObject()).Returns(new object()); var controller=new MyController(mockService.Object);

// Act var result=controller.MyAction() as ViewResult;

// Assert Assert.IsNotNull(result); var model=result.Model; Assert.IsInstanceOfType(model, typeof(object)); }}

通过这种方式,你可以避免直接在控制器中使用Session,而是通过依赖注入和抽象来管理会话状态,从而提高代码的可测试性。

如何准备ASP.NET MVC控制器使用Session同时是可测试的,所以本质上不使用Session而是使用一些Session抽象?我正在使用Ninject,因此您的示例可以基于此.

问题是Session对象在控制器中始终不可用(如在ctor中),但我需要在应用程序启动时将某些内容存储到Session(global.asax.cs也无法访问Session).

如果您希望您的类可以测试,请不要在那里使用不可测试的(外部)组件.当你试图模仿它们时,你只需要解决这个糟糕的设计.改为重新设计控制器.类不应该依赖外部/全局对象.这就是使用IoC的原因之一.

您可以通过两种方法将实施/基础架构详细信息与控制器分开:

>次要抽象

public interface ISession { string GetValue(string name); void SetValue(string name, string value); }

>域抽象.

public interface IStateData { bool IsPresent { get; } int MyDomainMeaningfulVariable { get; set; } }

在后一种情况下,接口会在会话中添加语义 – 强类型,命名良好的属性.这与使用NHibernate域实体而不是sqlreader [“DB_COLUMN_NAME”]一样.

然后,当然,将接口的HTTP实现(例如,使用HttpContext.Current)注入控制器.

模型粘合剂也是一种很好的方法,就像动作过滤器一样.他们是not just for form data.