10

我正在尝试模拟 HttpContext 以便我可以对控制器的 Request.IsAuthenicated 调用进行单元测试。我正在使用我在 Scott Hanselman 的博客中找到的代码来使用 rhino.mocks 来模拟 HttpContext。所以我有这个单元测试片:

PostsController postsController = new PostsController(postDL);
mocks.SetFakeControllerContext(postsController);
Expect.Call(postsController.Request.IsAuthenticated).Return(true);

在我的控制器操作中, if(Request.IsAuthenticated).... 当我尝试运行单元测试时,测试失败并抛出空异常,当我尝试调试单元测试时,我看到 HttpContext 从未分配给控制器。有任何想法吗?

4

6 回答 6

8

这应该有效:

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);
于 2008-10-27T13:55:46.130 回答
2

这可能对您有用,在类似的情况下为我工作:

http://haacked.com/archive/2007/06/19/unit-tests-web-code-without-a-web-server-using-httpssimulator.aspx

于 2008-10-27T10:04:47.983 回答
1

您可能会发现我写的这篇文章在某种程度上有所帮助 http://santoshbenjamin.wordpress.com/2008/08/04/mock-httpcontext-and-session-state/

欢呼班吉

于 2008-11-11T22:32:20.927 回答
0

现在,为了披露,我还没有弄脏你正在使用的大部分东西,但是:

如果你想模拟 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
}

然后,您可以在应用程序级别使用对任何一个的引用,是的,这意味着您必须在应用程序级别添加引用,并且您需要使用不同的 ref 而不是 Request,但您还可以完全控制身份验证以进行测试:)

仅供参考 - 这完全可以被炸开,我在大约一分钟内把它放在一起:)

于 2008-10-27T09:32:07.580 回答
0

这是一种伪造上下文的简单方法,从Jeff 的博客中找到:

        TextWriter tw = new StringWriter();
        HttpWorkerRequest wr = new SimpleWorkerRequest("/webapp", "c:\\inetpub\\wwwroot\\webapp\\", "default.aspx", "", tw);
        HttpContext.Current = new HttpContext(wr);
于 2011-09-21T12:51:30.297 回答
0

这是一个可能有用的类。它处理 ajax 请求、用户身份验证、请求参数等:https ://gist.github.com/3004119

于 2012-06-27T13:52:31.303 回答