在 Grails 的 Controller 单元测试中(更具体地说是 Spock 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()
}
}
但是测试失败了:
Expected exception java.lang.Exception, but no exception was thrown
我调试了执行并且没有抛出异常,exceptionThrowingMethod
的调用意外地返回了一个闭包。不要介意将 throws
声明添加到方法的签名中,这也不起作用。
我认为这与 Spock 有关,但我只使用 grails 的测试混合尝试了一个类似的测试并得到了相同的结果。这是我的尝试:
@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 的文档中找不到如何要求抛出异常,所以上面的代码对我来说听起来很自然。
我也发现通过谷歌搜索没有找到任何相关的东西是可疑的,所以也许我在测试方面做错了事。
这不是测试中的常见情况吗?您在特定场景中模拟某些方法的确定性行为,然后在这种场景发生时测试被测方法的预期行为。抛出异常对我来说似乎是一个有效的场景。
最佳答案
似乎使 demand
闭包无效(即没有隐式 it
参数,带有显式 ->
)does the trick :
serviceMock.demand.exceptionThrowingMethod {-> throw new Exception() }
更新:您也可以使用 Groovy 的原生 MockFor
类,它似乎不需要这种奇怪的闭包:
@TestFor(TestController)
class TestControllerTests {
void testException() {
def mock = new MockFor(TestService)
mock.demand.exceptionThrowingMethod { throw new Exception() }
controller.testService = mock.proxyInstance()
shouldFail { controller.triggerException() }
mock.verify(controller.testService)
}
}
请注意,当不使用 mock.use
时,必须使用 mock.verify
来验证模拟约束(即 exceptionThrowingMethod
被调用一次)。
关于unit-testing - 从 grails 模拟方法中抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9523966/