Reputation: 188
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
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
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
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
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
Reputation: 27127
This may be of some use to you, worked for me in a similar scenario:
Upvotes: 2
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