Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I test an event of a MVC controller

I want to test the OnException, OnActionExecuted event of an MVC controller.

If I use mock like this:

        var httpContext = MockRepository.GenerateMock<HttpContextBase>();
        var request = MockRepository.GenerateMock<HttpRequestBase>();

        httpContext.Expect(c => c.Request).Return(request).Repeat.AtLeastOnce();
        request.Expect(r => r.IsAuthenticated ).Return(true).Repeat.AtLeastOnce();


        var controller = new MyController() ;

        controller.ControllerContext = new ControllerContext(httpContext,
                                                             new RouteData(),
                                                             controller);

        var result = controller.Execute() as ViewResult;

…the action method is executing, but the events are not invoked.

like image 208
Lullaby Avatar asked Nov 05 '09 07:11

Lullaby


People also ask

Can you unit test controllers?

When unit testing controller logic, only the contents of a single action are tested, not the behavior of its dependencies or of the framework itself. Set up unit tests of controller actions to focus on the controller's behavior. A controller unit test avoids scenarios such as filters, routing, and model binding.

Can a unit test be performed on an MVC application without running the controllers in an ASP NET process?

unit tests do not run in the "MVC environment." They will run within the scope of the test runner, be that nunit, resharper,....

How do I create a controller unit test?

First we need to add an employee class in the Models folder. Following is the Employee class implementation. We need to add EmployeeController. Right-click on the controller folder in the solution explorer and select Add → Controller.

How unit testing is done in MVC?

Steps. Add a new unit test project to the MVC module solution. In Visual Studio's Solution Explorer, right-click on your MVC module solution and select Add > New Project. In the Add New Project dialog, select Unit Test Project, enter a name, and select the local folder to store it in.


1 Answers

This is one of the separation of concerns principles of MVC. When you're unit testing a method, you're testing the method itself independent of any filters applied to it. (And OnException() and OnActionExecuting() are really just glorified filters.)

If you want to test those other methods independently, you're free to do so. Normally the way you'd go about this is by calling the filters like so:

((IActionFilter)controller).OnActionExecuting(...)
((IExceptionFilter)controller).OnException(...)

You'll have to create context objects to pass to these methods. In the end, you have three unit tests: one for OnActionExecuting(), one for OnException(), and one for the actual method you're testing. The nice thing about this setup is that once you've unit tested the filters once, you don't have to worry about them any more for any other unit tests.

For example, if you have a Method1(), Method2(), and Method3(), you don't need to test each combination of method + filters. Simply have five unit tests: OnActionExecuting(), OnException(), Method1(), Method2(), and Method3(). This eliminates redundant testing and makes it easier to track down potential bugs in your code.

like image 132
Levi Avatar answered Sep 22 '22 12:09

Levi