Why does karate configure headers behave differently to setting headers directly in the background?

Viewed 146

I wrote a test that calls an api endpoint once and retrieves an etag in the response. After that I do a second call and I am setting the etag value to the if-none-match header. The test looks like the following:

Feature: Retrieve station properties

  Background:
    * url baseUrl
    * def contentType = 'application/vnd.whatever'
    * def accessToken = 'ey.foobar.123'
    * configure headers = { Authorization: '#("Bearer " + accessToken)', Accept: '#(contentType)' }

  Scenario: Fetch station properties once and expect a 304 on the sub-sequent request

    Given path '/api/station-properties'
    When method GET
    Then status 200
    And headers {ETag: '#notnull'}
    And def etag = responseHeaders['ETag'][0]

    Given path '/api/station-properties'
    And header If-None-Match = etag
    When method GET
    Then status 304

This basically works but I was not happy with the configure headers line as I may add additional headers later on. Thus I thought about using a different method to set the headers:

Feature: Retrieve station properties

  Background:
    * url baseUrl
    * def contentType = 'application/vnd.whatever'
    * def accessToken = 'ey.foobar.123'
    * header Authorization = 'Bearer ' + accessToken
    * header Accept = contentType

  Scenario: Fetch station properties once and expect a 304 on the sub-sequent request

    Given path '/api/station-properties'
    When method GET
    Then status 200
    And headers {ETag: '#notnull'}
    And def etag = responseHeaders['ETag'][0]

    Given path '/api/station-properties'
    And header If-None-Match = etag
    When method GET
    Then status 304

In this case though, the headers (Authorization and Accept) are set on the first api call but on the second call they are not.

Why is this the case?

1 Answers

Yes, the rule is configure is to "persist" for multiple HTTP calls. So just make this change in the Background:

* configure headers = ({ Authorization: 'Bearer ' + accessToken, Accept: contentType })

Well, yes - do what you were doing earlier. Now it should work.

Related