Throw an exception to the grails mock method

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.

+4
source share
1 answer

It seems that the closure of the demand closure is niladic (i.e. the absence of an implicit argument it with an explicit -> ) does the trick :

 serviceMock.demand.exceptionThrowingMethod {-> throw new Exception() } 

Update : you can also use the Groovy native MockFor , which doesn't seem to require this MockFor oddity:

 @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) } } 

Note that when mock.use is not used, mock.verify must be used to check layout constraints (i.e. that exceptionThrowingMethod was called once).

+8
source

Source: https://habr.com/ru/post/1399262/


All Articles