如何在ASP.Net Web表单中模拟/伪造会话对象?

Fik*_*kre 15 asp.net tdd session webforms mocking

有没有办法在创建单元测试时在ASP.Net Web表单中模拟/伪造会话对象?

我目前正在将用户详细信息存储在会话变量中,该变量由我的业务逻辑访问.

在单独测试我的业务逻辑时,会话不可用.这似乎表明一个糟糕的设计(虽然我不确定).业务逻辑层是否应该首先访问会话变量?

如果是这样,那么我将如何使用假对象交换用户详细信息进行测试?

Ben*_*eth 27

你可以用4行代码完成它.虽然这与先前关于将会话移出业务逻辑层的注释没有说明,但如果您正在使用与会话密切相关的遗留代码(我的方案),有时您可能需要这样做.

名称空间:

using System.Web;
using System.IO;
using System.Web.Hosting;
using System.Web.SessionState;
Run Code Online (Sandbox Code Playgroud)

代码:

HttpWorkerRequest _wr = new SimpleWorkerRequest(
    "/dummyWorkerRequest", @"c:\inetpub\wwwroot\dummy",
    "default.aspx", null, new StringWriter());

HttpContext.Current = new HttpContext(_wr);

var sessionContainer = new HttpSessionStateContainer(
    "id", new SessionStateItemCollection(),
    new HttpStaticObjectsCollection(), 10, true,
    HttpCookieMode.AutoDetect, SessionStateMode.InProc, false);

SessionStateUtility.AddHttpSessionStateToContext(
    HttpContext.Current, sessionContainer);
Run Code Online (Sandbox Code Playgroud)

然后,您可以在不收到NullReferenceException错误的情况下引用会话:

HttpContext.Current.Session.Add("mySessionKey", 1);
Run Code Online (Sandbox Code Playgroud)

这是我从以下文章编译的代码组合:


Mar*_*ann 9

在ASP.NET中,您无法创建HttpSessionState的Test Double,因为它是sealed.是的,这是ASP.NET原始设计者的糟糕设计,但是没有太多可做的事情.

这是为什么TDD'ers和其他SOLID实践者已经基本上放弃了ASP.NET而支持ASP.NET MVC和其他更可测试的框架的众多原因之一.在ASP.NET MVC中,HTTP会话由抽象的HttpSessionStateBase类建模.

您可以采用类似的方法让对象在抽象会话上工作,然后在ASP.NET环境中运行时包装真正的HttpSessionState类.根据具体情况,您甚至可以重用System.Web.Abstractions中的类型,但如果没有,您可以定义自己的类型.

在任何情况下,您的业务逻辑都是您的域模型,它应该独立于任何特定的运行时技术建模,所以我想说它不应该首先访问会话对象.

如果你绝对需要将测试双打用于涉及HttpSessionState的单位投注,那么对于某些侵入性动态模拟,例如TypeMockMoles,这仍然是可能的,尽管这些也带来了许多缺点(参见动态模拟的比较).