0

I have an interceptor that sets a property on the model object. In a unit test the model is null.

Interceptor

import groovy.transform.CompileStatic
import groovy.util.logging.Commons

@CompileStatic
@Commons
class FooInterceptor {

    FooInterceptor() {
        matchAll()
    }

    boolean after() {
        model.foo = 'bar'
        true
    }
}

Spec

import grails.test.mixin.TestFor
import spock.lang.Specification

@TestFor(FooInterceptor)
class FooInterceptorSpec extends Specification {
    void "Test Foo interceptor loads var to model"() {
        when: "A request matches the interceptor"
            withRequest(controller: 'foo', action: 'index')
            interceptor.after()

        then: "The interceptor loads the model"
            interceptor.doesMatch()
            interceptor.model.foo == 'bar'
    }
}

Stacktrace

Cannot set property 'foo' on null object
java.lang.NullPointerException: Cannot set property 'foo' on null object
    at bsb.core.web.FooInterceptor.after(FooInterceptor.groovy:13)
    at bsb.core.web.FooInterceptorSpec.Test Foo interceptor loads var to model(FooInterceptorSpec.groovy:9)
Kevan Ahlquist
  • 5,375
  • 1
  • 17
  • 25

1 Answers1

1

Setting the ModelAndView request attribute in the Spec solved the issue for us:

import grails.test.mixin.TestFor
import spock.lang.Specification

@TestFor(FooInterceptor)
class FooInterceptorSpec extends Specification {
    void "Test Foo interceptor loads var to model"() {
        given:
            interceptor.currentRequestAttributes().setAttribute(GrailsApplicationAttributes.MODEL_AND_VIEW, new ModelAndView('dummy', [:]), 0)

        when: "A request matches the interceptor"
            withRequest(controller: 'foo', action: 'index')
            interceptor.after()

        then: "The interceptor loads the model"
            interceptor.doesMatch()
            interceptor.model.foo == 'bar'
    }
}
Kevan Ahlquist
  • 5,375
  • 1
  • 17
  • 25