I want to mockup IPrincipal so I did this
public Mock<IPrincipal> Principal { get; set; }
in my setup of my nunit
Principal = new Mock<IPrincipal>();
So this should be all that I need in my nunit unit test but how about in my actual controller file?
Like how do I set it up?
For example I have a membership.Provider
So what I did was in my controller constructor I did
Provider = Membership.Provider;
So then in my controller I just used Provider.(whatever I need).
I am not sure how to setup the Principal thing in the same way.
Are you talking about ASP.NET MVC? I guess so.
You have to create an instance of the controller and set its RequestContext. You mock the HttpContext of the RequestContext, and inside this HttpContext, you mock its User property, and set it up to your mocked IPrincipal:
var principal = new Moq.Mock<IPrincipal>();
// ... mock IPrincipal as you wish
var httpContext = new Moq.Mock<HttpContextBase>();
httpContext.Setup(x => x.User).Returns(principal.Object);
// ... mock other httpContext's properties, methods, as needed
var reqContext = new RequestContext(httpContext.Object, new RouteData());
// now create the controller:
var controller = new MyController();
controller.ControllerContext =
new ControllerContext(reqContext, controller);
Hope this helps.
EDIT:
FYI, the User property on the Controller class comes from the HttpContext object, as you can see here (this is the getter method for the User property, obtained from Reflector -- you can download ASP.NET MVC source code as well):
public IPrincipal User
{
get
{
if (this.HttpContext != null)
{
return this.HttpContext.User;
}
return null;
}
}
If you now check the HttpContext property, you will see:
public HttpContextBase HttpContext
{
get
{
if (base.ControllerContext != null)
{
return base.ControllerContext.HttpContext;
}
return null;
}
}
So, everything until now was "read only". And we need a way to "inject" a mocked "User". So, we check that we can actually inject a ControllerContext object on the controller through a property. We verify how it is obtaining its "HttpContext" object, to know how to properly mock it up:
public virtual HttpContextBase HttpContext
{
get
{
if (this._httpContext == null)
{
this._httpContext = (this._requestContext != null) ? this._requestContext.HttpContext : new EmptyHttpContext();
}
return this._httpContext;
}
set
{
this._httpContext = value;
}
}
So, here we see that the ControllerContext object obtains it's HttpContext from a RequestContext object. So that might explain what I did above:
After all this magic, the controller will have no idea that you are calling it without an actual connection being made through a Web Server.
So, you can continue to use your "User" property inside your controller as usual, no changes must be done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With