How do I unit test private controller methods in ASP.NET MVC?
What is the best practice to unit-test private methods inside a controller in ASP.NET MVC? The Currently, if I want to unit-test a private method inside a controller I have to set it to public but when I do, that method is exposed to the web.
Is the best way to move t开发者_如何学Gohe method to a helper class?
You should be moving the method into a helper class that you extracted an interface to. That way it's easier to perform dependency injection and switch the underlaying implementation or mock it if needed.
Testing private methods is a code smell (or a test smell).
Use InternalsVisibleTo trick only when you must (i.e. you are using an untestable class and must raise an event that is hidden from you by a protected function call).
You should use the private object, like this:
var privateObject = new PrivateObject(this.controller);
var result = (ActionResult)privateObject.Invoke("RegisterToEvent", shippingAddressID, creditCardID);
you could set the method to internal instead of private, and then set the InternalsVisibleTo attribute to the name of your test assembly.
In assembly info:
[assembly: InternalsVisibleTo("MyTestAssembly")]
You could create an action filter for test methods like this....
public class TestActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.HttpContext.Response.Redirect("loginurl");
//or throw exception or some other action
}
}
Or you could make the method only publicly accessible to another assembly.
[assembly: InternalsVisibleTo("TestAssembly")]
You can work around that problem by limiting tests to visible methods. Any private method will be used at least by one visible method (otherwise: it can safely be deleted).
So I suggest to develop tests that call the visible methods with practical values so that the private algorithms are tested. If code is not reachable through visible methods - delete it.
I have used the PrivateObject() method but I like Charlino's suggestion of NonActionAttribute (see comments to original question above), too.
精彩评论