在创建单元测试时,ASP.Net Web Forms是否有一种方法来模拟/伪造会话对象?
我目前将用户详细信息存储在会话变量中,并由我的业务逻辑访问。
在隔离测试我的业务逻辑时,会话不可用。这似乎表明设计存在问题(尽管我不确定)。首先,业务逻辑层是否应该访问会话变量?
如果是这样,那么我应该如何用一个虚假对象交换用户详细信息进行测试?
在创建单元测试时,ASP.Net Web Forms是否有一种方法来模拟/伪造会话对象?
我目前将用户详细信息存储在会话变量中,并由我的业务逻辑访问。
在隔离测试我的业务逻辑时,会话不可用。这似乎表明设计存在问题(尽管我不确定)。首先,业务逻辑层是否应该访问会话变量?
如果是这样,那么我应该如何用一个虚假对象交换用户详细信息进行测试?
using System.Web;
using System.IO;
using System.Web.Hosting;
using System.Web.SessionState;
代码:
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);
之后您可以在没有获得NullReferenceException错误的情况下引用该会话:
HttpContext.Current.Session.Add("mySessionKey", 1);
这是我从下面的文章中编译的代码组合:
sealed
。是的,这是ASP.NET原始设计者不好的设计,但是没有太多可以做的事情。你的直觉是正确的——你不应该从业务逻辑中访问ASP.NET框架的部分,包括Session。
回答你的第一个问题,你可以使用像Typemock Isolator这样的产品来模拟静态类,但如果你重构代码以在接口(即IHttpSession)中包装对Session的访问,效果会更好。然后你就可以模拟IHttpSession了。
一种方法是将一个 lambda 表达式传递给您的代码,该表达式以字符串(或其他对象)作为输入,并使用它来设置 Session 对象或测试容器。
然而,正如其他人所说,最好将访问 Session 对象的操作从 BLL 中移出。