On the Grails unit test controller (more precisely, Spock ControllerSpec ), I would like to test the behavior of the tested method when calling and excluding a collaborator.
I use the mockFor utility (either from Spock UnitSpec or GrailsUnitTestMixin from Grails) to indicate my requirements for such an exception method in the test, for example:
@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) } }
So, inside triggerException I triggerException exceptionThrowingMethod , for example:
class TestController { def testService def triggerException() { testService.exceptionThrowingMethod() } }
But the test fails like:
Expected java.lang.Exception exception but no exception was thrown
I debugged the exception and the exception was not thrown bein, invokation exceptionThrowingMethod unexpectedly returns Closure. Nevermind adds a throws declaration to a method signature, also does not work.
I thought this was due to Spock, but I tried the simliar test using only Grails test mixins and got the same result. This was my attempt:
@TestFor(TestController) class TestControllerTests { void testException() { def serviceMock = mockFor(TestService) serviceMock.demand.exceptionThrowingMethod() { throw new Exception() } controller.testService = serviceMock.createMock() shouldFail(Exception) { controller.triggerException() } } }
Did you find something wrong in my code?
I could not find anywhere in Grails docs how to require an exception to make this code seem natural to me.
I also find it suspicious not to find anything related to a Google search, so maybe I'm trying to do something other than testing.
Is this not a common test case? You mock specific deterministic behavior of a method in a specific scenario, and then check the expected behavior of the test method when such a scenario occurs. Throwing an exception looked like a valid scenario for me.