【问题标题】:Unit testing grails controllers that use declarative exception handling使用声明性异常处理的单元测试 grails 控制器
【发布时间】:2014-10-30 00:19:05
【问题描述】:

假设我有以下代码:

class SomeController {     
   def fooService

   def controllerMethod() {
       def bar = fooService.doSomething()
       // render bar to user - success case
   }

   def fooExceptionHandler(FooException e) {
       // log, render error page, etc... 
   }
}

基于grails' new declarative controller exception handling mechanism,如果fooService.doSomething() 抛出异常,grails 会为我调用 fooExceptionHandler。伟大的。

现在当我对这个方法进行单元测试时(测试类使用@TestFor(SomeController) 注释),这将失败,说我们期望一个 FooException 但什么也没得到。

@Test(expected=FooException)
def doSomethingThrowsFooException() {
   // override default service behavior, trigger a FooException 
   controller.fooService = [ doSomething: { throw new FooException() }] 
   controller.controllerMethod()
}

但是,这是可行的:

@Test
def doSomethingThrowsFooException() {
   // override default service behavior, trigger a FooException 
   controller.fooService = [ doSomething: { throw new FooException() }] 
   controller.controllerMethod()
   assert response.json == false
}

所以测试这个方法的唯一方法是断言响应是预期的,但是由于声明性异常处理,这个逻辑现在在其他地方(单独测试),而不是在我正在测试的代码单元中.我的单元测试不应该只验证异常是从控制器方法中传播出来的吗?

【问题讨论】:

    标签: unit-testing grails


    【解决方案1】:

    如果可能的话,我会在集成测试中测试 fooService 与您的控制器的集成,但我认为只有在功能测试中才能真正明智地进行测试。您实际上是在测试 Grails - 您正在验证记录的行为是否发生在您的应用程序中。

    如果您添加一些代码来引发异常,然后添加额外的代码来捕获它并将其路由到处理程序,那么您只是在模拟 Grails 提供的东西。此类测试只是测试您的模拟代码,但与您的代码在生产环境中的运行情况无关。

    这里的单元测试机会在fooExceptionHandler 内部。测试给定一个异常,你用它做正确的事。

    【讨论】:

    • 让我看看我是否明白。在声明性异常处理之前,我的控制器在服务调用周围放置了一个 try/catch,并在 catch 中呈现了错误页面。现在不需要 try/catch,你是说我根本不需要对这条路径进行单元测试吗? (我明白你所说的关于单元测试 fooExceptionHandler 的意思)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-22
    • 1970-01-01
    • 2014-09-14
    相关资源
    最近更新 更多