2009-11-05 157 views
7

的事件我想测试OnExceptionOnActionExecuted事件的MVC控制器。如何测试一个MVC控制器

如果我使用的模拟像这样:

 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; 

...操作方法执行,但事件不被调用。

+1

我不知道你实际上已经连接到事件......你怎么知道他们不执行? – jrista 2009-11-05 07:38:55

+0

调试模式和断点 – Lullaby 2009-11-05 08:13:08

回答

15

这是分离的顾虑MVC的原则之一。当你在单元测试一个方法时,你正在测试方法本身,而不依赖于应用它的任何过滤器。 (和onException的()和OnActionExecuting()其实只是荣耀的过滤器。)

如果要单独测试的其他方法,你可以这样做。通常你会去了解这个方法是调用像这样的过滤器:

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

你必须创建上下文对象传递给这些方法。最后,你有三个单元测试:一个用于OnActionExecuting(),一个用于onException的(),以及一个用于正在测试的实际方法。关于这个设置的好处是,一旦你单元测试了一次过滤器,你就不必再为其他单元测试担心它们了。

例如,如果有一个方法1(),方法2()和方法3(),则不需要进行测试方法+过滤器的每一种组合。只需要五个单元测试:OnActionExecuting(),OnException(),Method1(),Method2()和Method3()。这消除了多余的测试,并且更容易追踪代码中的潜在错误。