我们说我有以下代码:
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
}
因此,测试此方法的唯一方法是声明响应是预期的,但由于声明性异常处理,此逻辑现在位于其他位置(单独测试),而不是我正在测试的代码单元。我的单元测试是否只能验证异常是否已从控制器方法中传播出来?
答案 0 :(得分:0)
如果可能的话,我会在集成测试中测试与控制器的fooService集成,但我认为在功能测试中它只是真正可测试的。您正在测试Grails - 您正在验证应用程序中是否存在记录的行为。
如果添加一些代码来抛出异常然后额外的代码来捕获它并将其路由到处理程序,那么你只是嘲笑Grails提供的东西。测试仅测试您的模拟代码,但与您的代码在生产中的工作效果无关。
此处的单元测试机会在fooExceptionHandler
内。测试给出异常,你用它做正确的事。