我有一个web服务,我试图单元测试。在服务中,它从HttpContext中提取了几个值,如下所示:
m_password = (string)HttpContext.Current.Session["CustomerId"];
m_userID = (string)HttpContext.Current.Session["CustomerUrl"];
在单元测试中,我使用一个简单的工作请求创建上下文,如下所示:
SimpleWorkerRequest request = new SimpleWorkerRequest("", "", "", null, new StringWriter());
HttpContext context = new HttpContext(request);
HttpContext.Current = context;
然而,每当我试图设置HttpContext.Current.Session的值时
HttpContext.Current.Session["CustomerId"] = "customer1";
HttpContext.Current.Session["CustomerUrl"] = "customer1Url";
我得到空引用异常,说HttpContext.Current.Session是空的。
是否有方法在单元测试中初始化当前会话?
从不嘲弄。从来没有!解决方法非常简单。为什么要伪造HttpContext这样一个美丽的作品呢?
下推会话!(这句话对我们大多数人来说已经足够理解了,但下面会详细解释)
(字符串)HttpContext.Current.Session(“CustomerId”);是我们现在访问它的方式。将其更改为
_customObject.SessionProperty("CustomerId")
当从test调用时,_customObject使用替代存储(DB或云键值[http://www.kvstore.io/])
但是当从实际应用程序调用时,_customObject使用Session。
这是怎么做到的?嗯…依赖注入!
因此test可以设置会话(地下),然后调用应用程序方法,就好像它对会话一无所知一样。然后测试秘密地检查应用程序代码是否正确地更新了会话。或者应用程序是否基于测试设置的会话值进行操作。
事实上,我们最终还是嘲笑了,尽管我说过:“永远不要嘲笑”。因为我们忍不住溜到下一个规则,“嘲笑最不疼的地方!”模拟巨大的HttpContext或模拟一个小的会话,哪个伤害最小?别问我这些规矩是从哪来的。我们就说常识吧。这里有一篇关于不要嘲笑单元测试会杀死我们的有趣文章
在asp.net Core / MVC 6 rc2中,你可以设置HttpContext
var SomeController controller = new SomeController();
controller.ControllerContext = new ControllerContext();
controller.ControllerContext.HttpContext = new DefaultHttpContext();
controller.HttpContext.Session = new DummySession();
Rc 1为
var SomeController controller = new SomeController();
controller.ActionContext = new ActionContext();
controller.ActionContext.HttpContext = new DefaultHttpContext();
controller.HttpContext.Session = new DummySession();
https://stackoverflow.com/a/34022964/516748
考虑使用Moq
new Mock<ISession>();
@Ro Hit给出的答案对我帮助很大,但我缺少用户凭据,因为我必须伪造一个用户进行身份验证单元测试。因此,让我描述一下我是如何解决它的。
根据此,如果添加方法
// using System.Security.Principal;
GenericPrincipal FakeUser(string userName)
{
var fakeIdentity = new GenericIdentity(userName);
var principal = new GenericPrincipal(fakeIdentity, null);
return principal;
}
然后追加
HttpContext.Current.User = FakeUser("myDomain\\myUser");
到TestSetup方法的最后一行就完成了,添加用户凭据并准备用于身份验证测试。
我还注意到HttpContext中还有其他你可能需要的部分,比如. mappath()方法。这里有一个可用的FakeHttpContext,它可以通过NuGet安装。