模拟 HttpContext 不起作用
Posted
技术标签:
【中文标题】模拟 HttpContext 不起作用【英文标题】:Mocking HttpContext doesn't work 【发布时间】:2008-10-27 04:09:36 【问题描述】:我正在尝试模拟 HttpContext,以便对控制器的 Request.IsAuthenicated 调用进行单元测试。我正在使用code that I found at Scott Hanselman's 博客使用 rhino.mocks 来模拟 HttpContext。 所以我有这个单元测试片:
PostsController postsController = new PostsController(postDL);
mocks.SetFakeControllerContext(postsController);
Expect.Call(postsController.Request.IsAuthenticated).Return(true);
在我的控制器操作中,我有类似的东西
if(Request.IsAuthenticated)....
当我尝试运行单元测试时,测试失败并抛出空异常,当我尝试调试单元测试时,我看到 HttpContext 从未分配给控制器。
有什么想法吗?
【问题讨论】:
【参考方案1】:这应该可行:
PostsController postsController = new PostsController(postDL);
var context = mocks.Stub<HttpContextBase>();
var request = mocks.Stub<HttpRequestBase>();
SetupResult.For(request.IsAuthenticated).Return(true);
SetupResult.For(context.Request).Return(request);
postsController.ControllerContext = new ControllerContext(context, new RouteData(), postsController);
【讨论】:
【参考方案2】:这可能对你有用,在类似的情况下为我工作:
http://haacked.com/archive/2007/06/19/unit-tests-web-code-without-a-web-server-using-httpsimulator.aspx
【讨论】:
当你没有 HttpContextBase 和相关的抽象基类时,这是一种蛮力方法 cmets 中有链接,为我工作:web.archive.org/web/20080731141201/http://haacked.com/code/…【参考方案3】:您可能会发现我写的这篇文章在某些方面有所帮助 http://santoshbenjamin.wordpress.com/2008/08/04/mock-httpcontext-and-session-state/
干杯 本杰
【讨论】:
【参考方案4】:现在,为了披露,我还没有弄脏你正在使用的大部分东西,但是:
如果你想模拟 IsAuthenticated,为什么不创建一个静态类来返回一个可以被你的测试代码操作的布尔值?
这有点粗糙,但希望你能明白:
interface IAuthenticationChecker
bool IsAuthenticated get;
public class MockAuthenticationChecker : IAuthenticationChecker
static bool _authenticated = false;
public static void SetAuthenticated(bool value)
_authenticated = value;
#region IAuthenticationChecker Members
public bool IsAuthenticated
get return _authenticated;
#endregion
public class RequestAuthenticationChecker : IAuthenticationChecker
#region IAuthenticationChecker Members
public bool IsAuthenticated
get
if (HttpContext.Current == null)
throw new ApplicationException(
"Unable to Retrieve IsAuthenticated for Request becuse there is no current HttpContext.");
return HttpContext.Current.Request.IsAuthenticated;
#endregion
然后您可以在应用级别使用对任何一个的引用,是的,这意味着您必须在应用级别添加引用,并且您需要使用不同的引用而不是请求,但您还可以完全控制身份验证测试:)
仅供参考 - 这完全可以被炸毁,我在大约一分钟内将它拼凑在一起:)
【讨论】:
【参考方案5】:这是一种伪造上下文的简单方法,从Jeff's blog 找到:
TextWriter tw = new StringWriter();
HttpWorkerRequest wr = new SimpleWorkerRequest("/webapp", "c:\\inetpub\\wwwroot\\webapp\\", "default.aspx", "", tw);
HttpContext.Current = new HttpContext(wr);
【讨论】:
【参考方案6】:这是一个可能有用的类。它处理 ajax 请求、用户身份验证、请求参数等:https://gist.github.com/3004119
【讨论】:
以上是关于模拟 HttpContext 不起作用的主要内容,如果未能解决你的问题,请参考以下文章