Search code examples
restfantomafbedsheet

How to verify a RESTful service that returns a HTTP 404, using Fancordion?


I'm writing a RESTful API in Fantom programming language. I'm using Fancordion to write the acceptance tests and have this scenario:

Country.fandoc

Country by Code
###############
Passing a country code as a parameter to the Country RESTful service must return the corresponding country
Example
-------
- Given the URL to get the details of Andorra [/country/AD]`set:countryUrl`
- When I send a HTTP GET request to it
- Then I expect the name to be [Andorra]`verifyEq:countryByCode.name`.

CountryFixture.fan

using afBedSheet
using afBounce
using afButter
using afFancordion
using util

@Fixture { specification=`specs/Country.fandoc` }
class CountryFixture : BaseFixture {

  Str? countryUrl

  Country countryByCode() {
    server := BedServer(AppModule#).startup
    client := server.makeClient
    response := client.sendRequest(ButterRequest(`$countryUrl`)).asStr
    Str:Obj? json := JsonInStream(response.in).readJson
    country := Country.fromJson(json)
    return country
  }
}

This works well. Now I want to verify that when an invalid country code is passed to the request, the RESTful service returns a HTTP 404 error, which it does, as I've implemented and verified using the browser. However, I haven't found in Fancordion documentation how can I verify that a HTTP 404 error is returned. What I'm getting instead is a fixture failure.

***
*** 1 Fixtures FAILED [6 Fixtures]
***

My acceptance test for this scenario is (appended to Country.fandoc):

Wrong Country Code
##################
Passing a wrong country code as a parameter to the Country RESTful service must cause it to return a HTTP 404 error

Example
-------
- Given the URL to get the details of country that does not exist [/country/XX]`set:countryUrl`
- When I send a HTTP GET request to it
- Then I expect a HTTP 404 error when I try `verifyEq:countryByCode`

How can I catch the 404, please?


Solution

  • If you're looking for something similar to a verifyErr(Type errType) method, Fancordion doesn't have one. That's because such methods are closely coupled to the implementation which doesn't really suit the style of Fancordion tests.

    Instead, disable the 404 Err raised by Butter with:

    client.errOn4xx.enabled = false
    

    And have the Fancordion fixture set the response.

    Uri? url
    ButterResponse? response
    
    Void httpGet() {
      client := BedServer(AppModule#).startup.makeClient
      client.errOn4xx.enabled = false
      this.response = client.get(url)
    }
    

    Then let the Fancordion specification verify the status code:

    Example
    -------
    - Given the URL to Unknown is [/country/XX]`set:url`
    - When I send a [HTTP GET request]`exe:httpGet`
    - Then I expect the returned status code to be [404]`eq:response.statusCode`.