13

I'm using the Groovy RESTClient class to do write some (spock) Acceptance tests for Java WebServices I've been authoring.

One frustration I've had is in testing the responses...

200 Status's are easy:

when:  def result = callServiceWithValidParams()
then:  result.status == 200

But with 400+ I'm forced to either wrap in a try-catch, or test for the HttpResponseException that RESTClient throws by default.

when:
    callWithInvalidParams()
then:
    def e = thrown(Exception)
    e.message == 'Bad Request'

This is sort-of OK, if a little frustrating... but I want to do better.

Ideally, I want my tests to more resemble this (might be confusing if you don't use groovy/spock)

@Unroll
def "should return #statusCode '#status' Response"()
{
    when:
    def result = restClient.get(path: PATH, query: [param: parameter])

    then:
    result.status == statusCode

    where:
    status         | statusCode | parameter                
    'OK'           | 200        | validParam
    'Bad Request'  | 400        | invalidParam
}

In the above example, the 'Bad Request' case fails. Instead of returning a value, restClient.get() throws HttpResponseException

Zach Lysobey
  • 14,959
  • 20
  • 95
  • 149
  • It's hard to understand the barrier your facing. Can you post more info? What type is params? What happens when you try to use the where block to define params? What does callService() look like? – Alex Blakemore Oct 23 '13 at 17:36
  • @AlexBlakemore thanks for the response. The example at the end is just meant to illustrate how my original request might help me. I see now that its somewhat confusing, as I don't actually show the RESTClient. Think of `callService(params)` as a wrapper around the client where the `params` values are maps of queryString params to be sent to the service. All of this is not really important though. The main point is that the RESTService returns a `result` for 200 responses, but throws an error for 400, 401, etc... so I cannot test the response in a standard way in my `then:` block – Zach Lysobey Oct 23 '13 at 17:42
  • Just editted the example to hopefully make more simple/clear. – Zach Lysobey Oct 23 '13 at 17:50
  • 1
    Then why not make a convenience method that wraps your REST calls that catches exceptions and turns them into status codes? – Alex Blakemore Oct 23 '13 at 17:52
  • I guess I could do that, but it will get a bit sloppy. For one, I'll have to create a way to map the error names (like 'Bad Request', 'Unauthorized'...) to the corresponding code (400, 401...) which aren't present in the HttpResponseException. When it comes down to it, that approach would be OK (and maybe merits an answer if you want some internet points), but I'm just hoping there may be a more elegant way to accomplish this. – Zach Lysobey Oct 23 '13 at 17:56

3 Answers3

17

@JonPeterson came up with what I think is a better solution, so I gave his answer the checkmark:

client.handler.failure = client.handler.success

More info here


The solution I (previously) landed on:

 restClient.handler.failure = { it }

Which is shorthand for

restClient.handler.failure = { resp -> return resp }

@JimmyLuong noted in the comments that this approach drops the data from the response, and suggested the following enhancement:

 restClient.handler.failure = { resp, data -> resp.setData(data); return resp }
Community
  • 1
  • 1
Zach Lysobey
  • 14,959
  • 20
  • 95
  • 149
  • 5
    Using this solution for me worked well, except for the data being dropped from the response. To get the data, I had to do something like: restClient.handler.failure = { resp, data -> resp.setData(data); return resp } – Jimmy Luong Jul 31 '14 at 10:26
  • The approach suggested by @TomaszKalkosiński is even simpler and works like a charm – xverges Jul 30 '15 at 22:45
11

As Tomasz already linked in a comment, here is my little one-liner answer from a similar question.

client.handler.failure = client.handler.success
Community
  • 1
  • 1
Jon Peterson
  • 2,966
  • 24
  • 32
1

One approach would be to make a Groovy convenience method that wraps your REST calls that catches exceptions and turns them into status codes

Alex Blakemore
  • 11,301
  • 2
  • 26
  • 49