Question

I have a Grails controller that expects an XML payload.

I fetch the XML payload like this in a Grails controller.

def xmlPayload = request.reader.text

That part works fine, but I'm struggling to mock this payload in a unit test.

I've tried both of the following, but the debugger is showing 'request.reader' to be null in both approaches.

Approach #1:

void "test controller method"(){
    setup:
    def mockBufferedReader = Mock( BufferedReader )
    mockBufferedReader.getText() >> '<hello/>'
    request.getReader() >> mockBufferedReader
    ....

Approach #2:

void "test controller method"(){
    setup:
    def mockBufferedReader = Mock( BufferedReader )
    mockBufferedReader.getText() >> '<hello/>'
    request.metaClass.getReader = { -> mockBufferedReader }
    ....

'request' in a unit test is a GrailsMockHttpServletRequest, so I presumed I could mock its methods like this (3rd line of both approaches), but so far no luck.

Thanks for any ideas.

Was it helpful?

Solution

You can do:

class EchoController {
    def echo () {
        render (request.reader.text)
    }
}


@TestFor(EchoController)
class EchoSpec extends Specification {
    def "echos XML data" () {
        request.XML = '<hello/>'

        when:
        controller.echo ()

        then:
        response.text == '<hello/>'
    }
}

See Testing XML and JSON Requests in Unit Testing Controllers.

OTHER TIPS

If you only need to provide contents for a request, then you don't need to mock anything.

 def "Spock works as expected"() {
    given:
    def request = new GrailsMockHttpServletRequest(content: '<hello/>')

    when:
    def result = request.getReader().getText()

    then:
    result == '<hello/>'
 }

One purpose of such Mock classes (as in Spring Test etc.) is to avoid explicit mocking with external libraries.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top