简体   繁体   中英

Grails - testing XML request does not behave as expected

I've been trying to define a test for consuming XML formatted request but I'm always getting null values. Here's the code:

In the spec:

void "Test XML"() {
    when:
    controller.request.xml = '<book><title>My Book</title></book>'
    controller.doStuff()

    then:
    response.text == "Book title: My Book"
}

In the controller:

def doStuff() {
    request.withFormat {
        xml { render "Book title: ${request.XML?.book?.title}" }
    }
}

This is pretty similar to what the official docs describe. However, I always get:

response.text == "Book title: My Book"
|        |    |
|        |    false
|        |    7 differences (63% similarity)
|        |    Book title: (null---)
|        |    Book title: (My Book)
|        Book title: null
org.codehaus.groovy.grails.plugins.testing.GrailsMockHttpServletResponse@61a48515

when I run the test. My JSON tests that follow the same pattern are fine though.

Update

Based on this StackOverflow question , I updated the controller code to the following:

def doStuff() {
    request.withFormat {
        xml {
            def book = new XmlSlurper().parseText(request.reader.text)
            render "Book title: ${book.title}"
        }
    }
}

and it works. I could use this as a work around, of course, but this doesn't answer the unexpected behavior of request.XML . It's null, which means that the request body doesn't get parsed automatically.

It seems that your root tag is translated to request.XML , for example:

class SimpleController {

    def consume() {
        request.withFormat {
            xml {
                render "The XML Title Is ${request.XML.title}."
            }
            json {
                render "The JSON Title Is ${request.JSON.title}."
            }
        }
    }

}

@TestFor(SimpleController)
class SimpleControllerSpec extends Specification {

    void 'test consume xml'() {
        when:
        request.xml = '<book><title>The Stand</title></book>'
        controller.consume()

        then:
        response.text == 'The XML Title Is The Stand.'
    }
}

Note that I not access book.title , but title directly.

In order to read mock request XML payload, a method has to be specified other than 'GET' which is default.

void "Test XML"() {
   when:
   controller.request.method='POST'
   controller.request.xml = '<book><title>My Book</title></book>'
   controller.doStuff()
   then:
   response.text == "Book title: My Book"
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM