Search code examples
ratpack

Unit testing exceptions with RequestFixture and HandlingResult in Ratpack


So I know how to properly check when an exception is thrown, on my handler unit tests.

However, what is the correct approach when I want to make sure an exception was not thrown?

This is the best I've come up with so far:

def "No exception is thrown"() {
    given:
    def noExceptionThrown = false

    when:
    def result =  RequestFixture.handle(new TestEndpoint(), { fixture -> fixture.uri("path/a)})

    then:
    try {
        result.exception(CustomException)
    } catch(ratpack.test.handling.HandlerExceptionNotThrownException e) {
        noExceptionThrown = (e != null)
    }

    noExceptionThrown
}

Solution

  • You could reorder the code a bit, so you can use Spock's thrown method:

    def "No exception is thrown"() {
        given:
        def result =  RequestFixture.handle(new TestEndpoint(), { fixture -> fixture.uri("path/a)})
    
        when:
        result.exception(CustomException)
    
        then:
        thrown(HandlerExceptionNotThrownException)
    }
    

    Another option is to use a custom error handler in the tests and add it to the registry of the fixture. The custom error handler can have methods to indicate an exception is thrown or not. See the following example:

    package sample
    
    import ratpack.error.ServerErrorHandler
    import ratpack.handling.Context
    import ratpack.handling.Handler
    import ratpack.test.handling.RequestFixture
    import spock.lang.Specification
    
    class HandlerSpec extends Specification {
    
        def 'check exception is thrown'() {
            given:
            def errorHandler = new TestErrorHandler()
    
            when:
            RequestFixture.handle(new SampleHandler(true), { fixture -> 
                fixture.registry.add ServerErrorHandler, errorHandler
            })
    
            then:
            errorHandler.exceptionThrown()
    
            and:
            errorHandler.throwable.message == 'Sample exception'
        }
    
        def 'check no exception is thrown'() {
            given:
            def errorHandler = new TestErrorHandler()
    
            when:
            RequestFixture.handle(new SampleHandler(false), { fixture ->
                fixture.registry.add ServerErrorHandler, errorHandler
            })
    
            then:
            errorHandler.noExceptionThrown()
        }
    
    }
    
    class SampleHandler implements Handler {
    
        private final boolean throwException = false
    
        SampleHandler(final boolean throwException) {
            this.throwException = throwException
        }
    
        @Override
        void handle(final Context ctx) throws Exception {
            if (throwException) {
                ctx.error(new Exception('Sample exception'))
            } else {
                ctx.response.send('OK')
            }
        }
    
    }
    
    class TestErrorHandler implements ServerErrorHandler {
    
        private Throwable throwable
    
        @Override
        void error(final Context context, final Throwable throwable) throws Exception {
            this.throwable = throwable
            context.response.status(500)
            context.response.send('NOK')
        }
    
        boolean exceptionThrown() {
            throwable != null
        }
    
        boolean noExceptionThrown() {
            !exceptionThrown()
        }
    }