Quantcast

Testing WithFormat closure with Accept headers

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Testing WithFormat closure with Accept headers

Jean-Henri Duteau
So I have a controller and I want to return XML or JSON depending on what is requested of me.  Grails supports that quite nicely with the withFormat closure.  But for the life of me, I can't figure out how to test this.

I've set up a test controller that just has the following method:

def show() {
println request.getHeader("Accept")
println response.getFormat()

withFormat {
xml { render "XML Format" }
json { render "JSON Format" }
}
}

In my sample test, I have the following:
@TestFor(TestController)
class TestControllerSpec extends spock.lang.Specification {
def "test accept XML header"() {
when:
request.addHeader "Accept", "application/xml"
controller.show()
then:
response.text == "XML Format"
}

def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.show()
then:
response.text == "JSON Format"
}
}

The XML test passes but only because the XML is the first line in the withFormat closure.  The JSON test fails.  In both cases, the output to the console is:

application/xml
all

So it appears that my test is setting the request Accept header properly, but Grails isn't determine what format the response should be in?  I've checked my Config.groovy and it has the right (i.e. default) mappings.  And since Groovy code is so hard to debug, I can't figure out what might be going wrong.

Jean Duteau
Director
Duteau Design Inc
Bus: 780-328-6395
Cell: 780-937-8991

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Testing WithFormat closure with Accept headers

Jean-Henri Duteau
As a follow up to this, if I set the format param in the test, then it works:
def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.params.format = 'json'
controller.show()
then:
response.text == "JSON Format"
}
application/json
json

That is obviously not due to the Accept header but due to the explicit setting of the format param.

Jean Duteau
Director
Duteau Design Inc
Bus: 780-328-6395
Cell: 780-937-8991

On 2012-07-27, at 6:14 PM, Jean-Henri Duteau wrote:

So I have a controller and I want to return XML or JSON depending on what is requested of me.  Grails supports that quite nicely with the withFormat closure.  But for the life of me, I can't figure out how to test this.

I've set up a test controller that just has the following method:

def show() {
println request.getHeader("Accept")
println response.getFormat()

withFormat {
xml { render "XML Format" }
json { render "JSON Format" }
}
}

In my sample test, I have the following:
@TestFor(TestController)
class TestControllerSpec extends spock.lang.Specification {
def "test accept XML header"() {
when:
request.addHeader "Accept", "application/xml"
controller.show()
then:
response.text == "XML Format"
}

def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.show()
then:
response.text == "JSON Format"
}
}

The XML test passes but only because the XML is the first line in the withFormat closure.  The JSON test fails.  In both cases, the output to the console is:

application/xml
all

So it appears that my test is setting the request Accept header properly, but Grails isn't determine what format the response should be in?  I've checked my Config.groovy and it has the right (i.e. default) mappings.  And since Groovy code is so hard to debug, I can't figure out what might be going wrong.

Jean Duteau
Director
Duteau Design Inc
Bus: 780-328-6395
Cell: 780-937-8991


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Testing WithFormat closure with Accept headers

Nathan Wells
Can you check your settings again? I looked at the docs and it doesn't match your test:


This shows json mapped to "text/json" where it appears you're using "application/json". I just checked my own application and I have the following mapping:

json: ['application/json','text/json']

So, it's totally possible you've got it right, that that's the default. I don't remember ever changing my mappings, at least. Just curious if the docs need to be updated.

Nathan Wells


On Fri, Jul 27, 2012 at 6:41 PM, Jean-Henri Duteau <[hidden email]> wrote:
As a follow up to this, if I set the format param in the test, then it works:
def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.params.format = 'json'

controller.show()
then:
response.text == "JSON Format"
}
application/json
json

That is obviously not due to the Accept header but due to the explicit setting of the format param.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991

On 2012-07-27, at 6:14 PM, Jean-Henri Duteau wrote:

So I have a controller and I want to return XML or JSON depending on what is requested of me.  Grails supports that quite nicely with the withFormat closure.  But for the life of me, I can't figure out how to test this.

I've set up a test controller that just has the following method:

def show() {
println request.getHeader("Accept")
println response.getFormat()

withFormat {
xml { render "XML Format" }
json { render "JSON Format" }
}
}

In my sample test, I have the following:
@TestFor(TestController)
class TestControllerSpec extends spock.lang.Specification {
def "test accept XML header"() {
when:
request.addHeader "Accept", "application/xml"
controller.show()
then:
response.text == "XML Format"
}

def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.show()
then:
response.text == "JSON Format"
}
}

The XML test passes but only because the XML is the first line in the withFormat closure.  The JSON test fails.  In both cases, the output to the console is:

application/xml
all

So it appears that my test is setting the request Accept header properly, but Grails isn't determine what format the response should be in?  I've checked my Config.groovy and it has the right (i.e. default) mappings.  And since Groovy code is so hard to debug, I can't figure out what might be going wrong.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Testing WithFormat closure with Accept headers

Jean-Henri Duteau
Here is what my default Config.groovy file looks contains for mime types:

grails.mime.file.extensions = false // enables the parsing of file extensions from URLs into the request format
grails.mime.use.accept.header = true
grails.mime.types = [
    all:           '*/*',
    atom:          'application/atom+xml',
    css:           'text/css',
    csv:           'text/csv',
    form:          'application/x-www-form-urlencoded',
    html:          ['text/html','application/xhtml+xml'],
    js:            'text/javascript',
    json:          ['application/json', 'text/json'],
    multipartForm: 'multipart/form-data',
    rss:           'application/rss+xml',
    text:          'text/plain',
    xml:           ['text/xml', 'application/xml']
]

I changed use.accept.header to be true but it didn't seem to have any effect, but I've left it like that, just in case.

I also added two more tests so that I'm checking application/xml, text/xml, application/json, and text/json.

Jean Duteau
Director
Duteau Design Inc
Bus: 780-328-6395
Cell: 780-937-8991

On 2012-07-27, at 8:55 PM, Nathan Wells wrote:

Can you check your settings again? I looked at the docs and it doesn't match your test:


This shows json mapped to "text/json" where it appears you're using "application/json". I just checked my own application and I have the following mapping:

json: ['application/json','text/json']

So, it's totally possible you've got it right, that that's the default. I don't remember ever changing my mappings, at least. Just curious if the docs need to be updated.

Nathan Wells


On Fri, Jul 27, 2012 at 6:41 PM, Jean-Henri Duteau <[hidden email]> wrote:
As a follow up to this, if I set the format param in the test, then it works:
def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.params.format = 'json'

controller.show()
then:
response.text == "JSON Format"
}
application/json
json

That is obviously not due to the Accept header but due to the explicit setting of the format param.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991

On 2012-07-27, at 6:14 PM, Jean-Henri Duteau wrote:

So I have a controller and I want to return XML or JSON depending on what is requested of me.  Grails supports that quite nicely with the withFormat closure.  But for the life of me, I can't figure out how to test this.

I've set up a test controller that just has the following method:

def show() {
println request.getHeader("Accept")
println response.getFormat()

withFormat {
xml { render "XML Format" }
json { render "JSON Format" }
}
}

In my sample test, I have the following:
@TestFor(TestController)
class TestControllerSpec extends spock.lang.Specification {
def "test accept XML header"() {
when:
request.addHeader "Accept", "application/xml"
controller.show()
then:
response.text == "XML Format"
}

def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.show()
then:
response.text == "JSON Format"
}
}

The XML test passes but only because the XML is the first line in the withFormat closure.  The JSON test fails.  In both cases, the output to the console is:

application/xml
all

So it appears that my test is setting the request Accept header properly, but Grails isn't determine what format the response should be in?  I've checked my Config.groovy and it has the right (i.e. default) mappings.  And since Groovy code is so hard to debug, I can't figure out what might be going wrong.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991




Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Testing WithFormat closure with Accept headers

Nathan Wells
Well, for what it's worth, I'm able to reproduce your issue really easily:


I'd say this looks like a bug, but I'm also not sure if withFormat is supposed to work in a unit test. Not sure why it wouldn't other than it's not strictly part of your controller code. Anyone more expert that can confirm or deny?

Nathan Wells


On Fri, Jul 27, 2012 at 9:14 PM, Jean-Henri Duteau <[hidden email]> wrote:
Here is what my default Config.groovy file looks contains for mime types:

grails.mime.file.extensions = false // enables the parsing of file extensions from URLs into the request format
grails.mime.use.accept.header = true
grails.mime.types = [
    all:           '*/*',
    atom:          'application/atom+xml',
    css:           'text/css',
    csv:           'text/csv',
    form:          'application/x-www-form-urlencoded',
    html:          ['text/html','application/xhtml+xml'],
    js:            'text/javascript',
    json:          ['application/json', 'text/json'],
    multipartForm: 'multipart/form-data',
    rss:           'application/rss+xml',
    text:          'text/plain',
    xml:           ['text/xml', 'application/xml']
]

I changed use.accept.header to be true but it didn't seem to have any effect, but I've left it like that, just in case.

I also added two more tests so that I'm checking application/xml, text/xml, application/json, and text/json.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991

On 2012-07-27, at 8:55 PM, Nathan Wells wrote:

Can you check your settings again? I looked at the docs and it doesn't match your test:


This shows json mapped to "text/json" where it appears you're using "application/json". I just checked my own application and I have the following mapping:

json: ['application/json','text/json']

So, it's totally possible you've got it right, that that's the default. I don't remember ever changing my mappings, at least. Just curious if the docs need to be updated.

Nathan Wells


On Fri, Jul 27, 2012 at 6:41 PM, Jean-Henri Duteau <[hidden email]> wrote:
As a follow up to this, if I set the format param in the test, then it works:
def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.params.format = 'json'

controller.show()
then:
response.text == "JSON Format"
}
application/json
json

That is obviously not due to the Accept header but due to the explicit setting of the format param.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991

On 2012-07-27, at 6:14 PM, Jean-Henri Duteau wrote:

So I have a controller and I want to return XML or JSON depending on what is requested of me.  Grails supports that quite nicely with the withFormat closure.  But for the life of me, I can't figure out how to test this.

I've set up a test controller that just has the following method:

def show() {
println request.getHeader("Accept")
println response.getFormat()

withFormat {
xml { render "XML Format" }
json { render "JSON Format" }
}
}

In my sample test, I have the following:
@TestFor(TestController)
class TestControllerSpec extends spock.lang.Specification {
def "test accept XML header"() {
when:
request.addHeader "Accept", "application/xml"
controller.show()
then:
response.text == "XML Format"
}

def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.show()
then:
response.text == "JSON Format"
}
}

The XML test passes but only because the XML is the first line in the withFormat closure.  The JSON test fails.  In both cases, the output to the console is:

application/xml
all

So it appears that my test is setting the request Accept header properly, but Grails isn't determine what format the response should be in?  I've checked my Config.groovy and it has the right (i.e. default) mappings.  And since Groovy code is so hard to debug, I can't figure out what might be going wrong.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991





Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Testing WithFormat closure with Accept headers

Jean-Henri Duteau
Just to add some further confusion, I've added some integration tests that test the withFormat call.

If I run my integration tests inside of STSv3 (or G2TS v3 now) via a Run As->Grails command (test-app), all of my tests pass because I'm setting the params.format to json.  But if I run them *outside* of STS, i.e from the command-line using grails test-app, I get the following error:

java.lang.NullPointerException: Cannot invoke method getAt() on null object
	at com.healthfire.ConformanceController.show(ConformanceController.groovy:19)
	at com.healthfire.ConformanceControllerIntegrationSpec.convert one conformance to JSON(ConformanceControllerIntegrationSpec.groovy:86)
And what is line 19 of my ConformanceController you ask?  Yep, the "withFormat {" line. :)

Jean Duteau
Director
Duteau Design Inc
Bus: 780-328-6395
Cell: 780-937-8991

On 2012-07-27, at 10:18 PM, Nathan Wells wrote:

Well, for what it's worth, I'm able to reproduce your issue really easily:


I'd say this looks like a bug, but I'm also not sure if withFormat is supposed to work in a unit test. Not sure why it wouldn't other than it's not strictly part of your controller code. Anyone more expert that can confirm or deny?

Nathan Wells


On Fri, Jul 27, 2012 at 9:14 PM, Jean-Henri Duteau <[hidden email]> wrote:
Here is what my default Config.groovy file looks contains for mime types:

grails.mime.file.extensions = false // enables the parsing of file extensions from URLs into the request format
grails.mime.use.accept.header = true
grails.mime.types = [
    all:           '*/*',
    atom:          'application/atom+xml',
    css:           'text/css',
    csv:           'text/csv',
    form:          'application/x-www-form-urlencoded',
    html:          ['text/html','application/xhtml+xml'],
    js:            'text/javascript',
    json:          ['application/json', 'text/json'],
    multipartForm: 'multipart/form-data',
    rss:           'application/rss+xml',
    text:          'text/plain',
    xml:           ['text/xml', 'application/xml']
]

I changed use.accept.header to be true but it didn't seem to have any effect, but I've left it like that, just in case.

I also added two more tests so that I'm checking application/xml, text/xml, application/json, and text/json.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991

On 2012-07-27, at 8:55 PM, Nathan Wells wrote:

Can you check your settings again? I looked at the docs and it doesn't match your test:


This shows json mapped to "text/json" where it appears you're using "application/json". I just checked my own application and I have the following mapping:

json: ['application/json','text/json']

So, it's totally possible you've got it right, that that's the default. I don't remember ever changing my mappings, at least. Just curious if the docs need to be updated.

Nathan Wells


On Fri, Jul 27, 2012 at 6:41 PM, Jean-Henri Duteau <[hidden email]> wrote:
As a follow up to this, if I set the format param in the test, then it works:
def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.params.format = 'json'

controller.show()
then:
response.text == "JSON Format"
}
application/json
json

That is obviously not due to the Accept header but due to the explicit setting of the format param.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991

On 2012-07-27, at 6:14 PM, Jean-Henri Duteau wrote:

So I have a controller and I want to return XML or JSON depending on what is requested of me.  Grails supports that quite nicely with the withFormat closure.  But for the life of me, I can't figure out how to test this.

I've set up a test controller that just has the following method:

def show() {
println request.getHeader("Accept")
println response.getFormat()

withFormat {
xml { render "XML Format" }
json { render "JSON Format" }
}
}

In my sample test, I have the following:
@TestFor(TestController)
class TestControllerSpec extends spock.lang.Specification {
def "test accept XML header"() {
when:
request.addHeader "Accept", "application/xml"
controller.show()
then:
response.text == "XML Format"
}

def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.show()
then:
response.text == "JSON Format"
}
}

The XML test passes but only because the XML is the first line in the withFormat closure.  The JSON test fails.  In both cases, the output to the console is:

application/xml
all

So it appears that my test is setting the request Accept header properly, but Grails isn't determine what format the response should be in?  I've checked my Config.groovy and it has the right (i.e. default) mappings.  And since Groovy code is so hard to debug, I can't figure out what might be going wrong.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991






Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Testing WithFormat closure with Accept headers

craigatkinson
It's a little non-intuitive, but in unit testing you can control which 'withFormat' block gets executed by setting the format on the reponse before calling the controller action:

controller.response.format = 'json'
controller.show()

Hope this helps,
Craig

On Sun, Jul 29, 2012 at 12:07 AM, Jean-Henri Duteau <[hidden email]> wrote:
Just to add some further confusion, I've added some integration tests that test the withFormat call.

If I run my integration tests inside of STSv3 (or G2TS v3 now) via a Run As->Grails command (test-app), all of my tests pass because I'm setting the params.format to json.  But if I run them *outside* of STS, i.e from the command-line using grails test-app, I get the following error:

java.lang.NullPointerException: Cannot invoke method getAt() on null object
	at com.healthfire.ConformanceController.show(ConformanceController.groovy:19)
	at com.healthfire.ConformanceControllerIntegrationSpec.convert one conformance to JSON(ConformanceControllerIntegrationSpec.groovy:86)
And what is line 19 of my ConformanceController you ask?  Yep, the "withFormat {" line. :)

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991

On 2012-07-27, at 10:18 PM, Nathan Wells wrote:

Well, for what it's worth, I'm able to reproduce your issue really easily:


I'd say this looks like a bug, but I'm also not sure if withFormat is supposed to work in a unit test. Not sure why it wouldn't other than it's not strictly part of your controller code. Anyone more expert that can confirm or deny?

Nathan Wells


On Fri, Jul 27, 2012 at 9:14 PM, Jean-Henri Duteau <[hidden email]> wrote:
Here is what my default Config.groovy file looks contains for mime types:

grails.mime.file.extensions = false // enables the parsing of file extensions from URLs into the request format
grails.mime.use.accept.header = true
grails.mime.types = [
    all:           '*/*',
    atom:          'application/atom+xml',
    css:           'text/css',
    csv:           'text/csv',
    form:          'application/x-www-form-urlencoded',
    html:          ['text/html','application/xhtml+xml'],
    js:            'text/javascript',
    json:          ['application/json', 'text/json'],
    multipartForm: 'multipart/form-data',
    rss:           'application/rss+xml',
    text:          'text/plain',
    xml:           ['text/xml', 'application/xml']
]

I changed use.accept.header to be true but it didn't seem to have any effect, but I've left it like that, just in case.

I also added two more tests so that I'm checking application/xml, text/xml, application/json, and text/json.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991

On 2012-07-27, at 8:55 PM, Nathan Wells wrote:

Can you check your settings again? I looked at the docs and it doesn't match your test:


This shows json mapped to "text/json" where it appears you're using "application/json". I just checked my own application and I have the following mapping:

json: ['application/json','text/json']

So, it's totally possible you've got it right, that that's the default. I don't remember ever changing my mappings, at least. Just curious if the docs need to be updated.

Nathan Wells


On Fri, Jul 27, 2012 at 6:41 PM, Jean-Henri Duteau <[hidden email]> wrote:
As a follow up to this, if I set the format param in the test, then it works:
def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.params.format = 'json'

controller.show()
then:
response.text == "JSON Format"
}
application/json
json

That is obviously not due to the Accept header but due to the explicit setting of the format param.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991

On 2012-07-27, at 6:14 PM, Jean-Henri Duteau wrote:

So I have a controller and I want to return XML or JSON depending on what is requested of me.  Grails supports that quite nicely with the withFormat closure.  But for the life of me, I can't figure out how to test this.

I've set up a test controller that just has the following method:

def show() {
println request.getHeader("Accept")
println response.getFormat()

withFormat {
xml { render "XML Format" }
json { render "JSON Format" }
}
}

In my sample test, I have the following:
@TestFor(TestController)
class TestControllerSpec extends spock.lang.Specification {
def "test accept XML header"() {
when:
request.addHeader "Accept", "application/xml"
controller.show()
then:
response.text == "XML Format"
}

def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.show()
then:
response.text == "JSON Format"
}
}

The XML test passes but only because the XML is the first line in the withFormat closure.  The JSON test fails.  In both cases, the output to the console is:

application/xml
all

So it appears that my test is setting the request Accept header properly, but Grails isn't determine what format the response should be in?  I've checked my Config.groovy and it has the right (i.e. default) mappings.  And since Groovy code is so hard to debug, I can't figure out what might be going wrong.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991







Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Testing WithFormat closure with Accept headers

Jean-Henri Duteau
Yes, I know I can do that, but that sort of ruins the point of unit testing the Accept headers working properly.

Jean Duteau
Director
Duteau Design Inc
Bus: 780-328-6395
Cell: 780-937-8991

On 2012-07-30, at 9:53 AM, Craig Atkinson wrote:

It's a little non-intuitive, but in unit testing you can control which 'withFormat' block gets executed by setting the format on the reponse before calling the controller action:

controller.response.format = 'json'
controller.show()

Hope this helps,
Craig

On Sun, Jul 29, 2012 at 12:07 AM, Jean-Henri Duteau <[hidden email]> wrote:
Just to add some further confusion, I've added some integration tests that test the withFormat call.

If I run my integration tests inside of STSv3 (or G2TS v3 now) via a Run As->Grails command (test-app), all of my tests pass because I'm setting the params.format to json.  But if I run them *outside* of STS, i.e from the command-line using grails test-app, I get the following error:

java.lang.NullPointerException: Cannot invoke method getAt() on null object
	at com.healthfire.ConformanceController.show(ConformanceController.groovy:19)
	at com.healthfire.ConformanceControllerIntegrationSpec.convert one conformance to JSON(ConformanceControllerIntegrationSpec.groovy:86)
And what is line 19 of my ConformanceController you ask?  Yep, the "withFormat {" line. :)

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991

On 2012-07-27, at 10:18 PM, Nathan Wells wrote:

Well, for what it's worth, I'm able to reproduce your issue really easily:


I'd say this looks like a bug, but I'm also not sure if withFormat is supposed to work in a unit test. Not sure why it wouldn't other than it's not strictly part of your controller code. Anyone more expert that can confirm or deny?

Nathan Wells


On Fri, Jul 27, 2012 at 9:14 PM, Jean-Henri Duteau <[hidden email]> wrote:
Here is what my default Config.groovy file looks contains for mime types:

grails.mime.file.extensions = false // enables the parsing of file extensions from URLs into the request format
grails.mime.use.accept.header = true
grails.mime.types = [
    all:           '*/*',
    atom:          'application/atom+xml',
    css:           'text/css',
    csv:           'text/csv',
    form:          'application/x-www-form-urlencoded',
    html:          ['text/html','application/xhtml+xml'],
    js:            'text/javascript',
    json:          ['application/json', 'text/json'],
    multipartForm: 'multipart/form-data',
    rss:           'application/rss+xml',
    text:          'text/plain',
    xml:           ['text/xml', 'application/xml']
]

I changed use.accept.header to be true but it didn't seem to have any effect, but I've left it like that, just in case.

I also added two more tests so that I'm checking application/xml, text/xml, application/json, and text/json.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991

On 2012-07-27, at 8:55 PM, Nathan Wells wrote:

Can you check your settings again? I looked at the docs and it doesn't match your test:


This shows json mapped to "text/json" where it appears you're using "application/json". I just checked my own application and I have the following mapping:

json: ['application/json','text/json']

So, it's totally possible you've got it right, that that's the default. I don't remember ever changing my mappings, at least. Just curious if the docs need to be updated.

Nathan Wells


On Fri, Jul 27, 2012 at 6:41 PM, Jean-Henri Duteau <[hidden email]> wrote:
As a follow up to this, if I set the format param in the test, then it works:
def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.params.format = 'json'

controller.show()
then:
response.text == "JSON Format"
}
application/json
json

That is obviously not due to the Accept header but due to the explicit setting of the format param.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991

On 2012-07-27, at 6:14 PM, Jean-Henri Duteau wrote:

So I have a controller and I want to return XML or JSON depending on what is requested of me.  Grails supports that quite nicely with the withFormat closure.  But for the life of me, I can't figure out how to test this.

I've set up a test controller that just has the following method:

def show() {
println request.getHeader("Accept")
println response.getFormat()

withFormat {
xml { render "XML Format" }
json { render "JSON Format" }
}
}

In my sample test, I have the following:
@TestFor(TestController)
class TestControllerSpec extends spock.lang.Specification {
def "test accept XML header"() {
when:
request.addHeader "Accept", "application/xml"
controller.show()
then:
response.text == "XML Format"
}

def "test accept JSON header"() {
when:
request.addHeader "Accept", "application/json"
controller.show()
then:
response.text == "JSON Format"
}
}

The XML test passes but only because the XML is the first line in the withFormat closure.  The JSON test fails.  In both cases, the output to the console is:

application/xml
all

So it appears that my test is setting the request Accept header properly, but Grails isn't determine what format the response should be in?  I've checked my Config.groovy and it has the right (i.e. default) mappings.  And since Groovy code is so hard to debug, I can't figure out what might be going wrong.

Jean Duteau
Director
Duteau Design Inc
Bus: <a href="tel:780-328-6395" value="+17803286395" target="_blank">780-328-6395
Cell: <a href="tel:780-937-8991" value="+17809378991" target="_blank">780-937-8991








Loading...