VolkanUzun
VolkanUzun

Reputation: 188

Mocking HttpContext doesn't work

I am trying to mock out HttpContext so that I can unit test my controller's Request.IsAuthenicated call. I am using the code that I found at Scott Hanselman's blog to simulate HttpContext using rhino.mocks. so i have this unit test piece:

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

In my controller action, I have something like if(Request.IsAuthenticated).... when I try to run the unit test, the test fails throwing a null exception, and when I try to debug the unit test, I see that the HttpContext is never assigned to the controller. any ideas?

Upvotes: 10

Views: 5249

Answers (6)

ciscoheat
ciscoheat

Reputation: 3947

Here's a class that may be useful. It handles ajax requests, user authentication, request parameters and more: https://gist.github.com/3004119

Upvotes: 0

Lauri I
Lauri I

Reputation: 228

Here is one simple way to fake the context, found it from Jeff's blog :

        TextWriter tw = new StringWriter();
        HttpWorkerRequest wr = new SimpleWorkerRequest("/webapp", "c:\\inetpub\\wwwroot\\webapp\\", "default.aspx", "", tw);
        HttpContext.Current = new HttpContext(wr);

Upvotes: 0

Santosh Benjamin
Santosh Benjamin

Reputation: 81

You may find the post I wrote on this to be helpful in some way http://santoshbenjamin.wordpress.com/2008/08/04/mock-httpcontext-and-session-state/

cheers benjy

Upvotes: 1

Tim Scott
Tim Scott

Reputation: 15205

This should work:

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);

Upvotes: 8

Kieron
Kieron

Reputation: 27127

This may be of some use to you, worked for me in a similar scenario:

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

Upvotes: 2

Rob Cooper
Rob Cooper

Reputation: 28877

Now, for disclosure, I have yet to get my hands dirty with most of the stuff you are working with, however:

If you want to mock the IsAuthenticated, why not just create a static class to return a bool that can the be manipulated by your test code?

This is a bit rough round the edges, but hopefully you get the idea:

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
}

You can then use a reference to either at app level, yeah it means you have to add a reference at app level, and you need to use a different ref rather than Request, but you also get complete control over the authentication for testing :)

FYI - this is totally open to being blown apart, I threw it together in about a minute :)

Upvotes: 0

Related Questions