在测试初始化方法中模拟 HttpContext.Current [英] Mock HttpContext.Current in Test Init Method
问题描述
我正在尝试向我构建的 ASP.NET MVC 应用程序添加单元测试.在我的单元测试中,我使用以下代码:
I'm trying to add unit testing to an ASP.NET MVC application I have built. In my unit tests I use the following code:
[TestMethod]
public void IndexAction_Should_Return_View() {
var controller = new MembershipController();
controller.SetFakeControllerContext("TestUser");
...
}
使用以下助手模拟控制器上下文:
With the following helpers to mock the controller context:
public static class FakeControllerContext {
public static HttpContextBase FakeHttpContext(string username) {
var context = new Mock<HttpContextBase>();
context.SetupGet(ctx => ctx.Request.IsAuthenticated).Returns(!string.IsNullOrEmpty(username));
if (!string.IsNullOrEmpty(username))
context.SetupGet(ctx => ctx.User.Identity).Returns(FakeIdentity.CreateIdentity(username));
return context.Object;
}
public static void SetFakeControllerContext(this Controller controller, string username = null) {
var httpContext = FakeHttpContext(username);
var context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
controller.ControllerContext = context;
}
}
此测试类继承自具有以下内容的基类:
This test class inherits from a base class which has the following:
[TestInitialize]
public void Init() {
...
}
在这个方法中,它调用一个库(我无法控制)它试图运行以下代码:
Inside this method it calls a library (which i have no control over) which tries to run the following code:
HttpContext.Current.User.Identity.IsAuthenticated
现在您大概可以看到问题所在了.我已经针对控制器设置了假 HttpContext,但没有在这个基本的 Init 方法中设置.单元测试/模拟对我来说很新,所以我想确保我做对了.我模拟 HttpContext 以便它在我的控制器和在我的 Init 方法中调用的任何库共享的正确方法是什么.
Now you can probably see the problem. I have set the fake HttpContext against the controller but not in this base Init method. Unit testing / mocking is very new to me so I want to make sure I get this right. What is the correct way for me to Mock out the HttpContext so that it is shared across my controller and any libraries which are called in my Init method.
推荐答案
HttpContext.Current
返回 System.Web.HttpContext
,不扩展 System.Web.HttpContextBase
.HttpContextBase
是后来添加的,以解决 HttpContext
难以模拟的问题.这两个类基本上不相关(HttpContextWrapper
是用作它们之间的适配器).
HttpContext.Current
returns an instance of System.Web.HttpContext
, which does not extend System.Web.HttpContextBase
. HttpContextBase
was added later to address HttpContext
being difficult to mock. The two classes are basically unrelated (HttpContextWrapper
is used as an adapter between them).
幸运的是,HttpContext
本身是可伪造的,足以让您替换 IPrincipal
(用户)和 IIdentity
.
Fortunately, HttpContext
itself is fakeable just enough for you do replace the IPrincipal
(User) and IIdentity
.
以下代码按预期运行,即使在控制台应用程序中:
The following code runs as expected, even in a console application:
HttpContext.Current = new HttpContext(
new HttpRequest("", "http://tempuri.org", ""),
new HttpResponse(new StringWriter())
);
// User is logged in
HttpContext.Current.User = new GenericPrincipal(
new GenericIdentity("username"),
new string[0]
);
// User is logged out
HttpContext.Current.User = new GenericPrincipal(
new GenericIdentity(String.Empty),
new string[0]
);
这篇关于在测试初始化方法中模拟 HttpContext.Current的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!