在Grails的控制器单元测试中(更具体地说是Spock的
我使用mockFor工具(来自Spock的UnitSpec或Grails的GrailsUnitTestMixin)来指定测试中对于这种抛出异常方法的需求,像这样:
因此,在
ControllerSpec
),我想要检查被测试方法在协作者抛出异常时的行为。我使用mockFor工具(来自Spock的UnitSpec或Grails的GrailsUnitTestMixin)来指定测试中对于这种抛出异常方法的需求,像这样:
@TestFor(TestController)
class TestControllerSpec extends Specification {
def "throwing and exception from a mock method should make the test fail"() {
setup:
def serviceMock = mockFor(TestService)
serviceMock.demand.exceptionThrowingMethod() { throw new Exception() }
controller.testService = serviceMock.createMock()
when:
controller.triggerException()
then:
thrown(Exception)
}
}
因此,在
triggerException
中,我会像这样调用 exceptionThrowingMethod
:class TestController {
def testService
def triggerException() {
testService.exceptionThrowingMethod()
}
}
但是测试失败了,错误信息如下:
期望抛出 java.lang.Exception 异常,但没有抛出异常
我调试了程序,发现并没有抛出异常,调用 exceptionThrowingMethod
竟然返回了一个闭包。即使在方法签名中添加 throws
声明也不起作用。
我以为这与 Spock 有关,但我尝试使用 Grails 的测试 mixin 进行类似的测试,结果也是一样的。这是我的尝试:
@TestFor(TestController)
class TestControllerTests {
void testException() {
def serviceMock = mockFor(TestService)
serviceMock.demand.exceptionThrowingMethod() { throw new Exception() }
controller.testService = serviceMock.createMock()
shouldFail(Exception) {
controller.triggerException()
}
}
}
你发现代码中有什么问题吗?
在Grails文档中我没有找到如何强制抛出异常的方法,所以上述代码对我来说是很自然的。
通过谷歌搜索也没有找到相关信息,这让我觉得可能在测试方面我正在尝试做错误的事情。
这不是测试中常见的情况吗?你可以在特定场景下模拟某些方法的确定性行为,然后测试当发生这种情况时被测试方法的预期行为。对我来说,抛出异常看起来像是一个有效的情形。