Having a POJO like feature in KarateAPI?

I have been using Karate and RestAssured for sometime. There are advantages and downside of both tools of course. Right now I have a RestAssured project where I have Request and Response object and POJOs. My requests wraps my endpoint and send my POJOs to those endpoint. I do all my Headers, etc configuration in an abstract layer. In case I need to override them, I override them during the test. If not, Its a two lines of code for me to trigger an endpoint.

My way of working with happy path and negative path of an edpoint is that I initialize the POJO before every test with new values in the constructor. Then I override the value that I want in test scope. For example, if I want to test a negative case for password field, I set this field to empty string during the test. But other fields are already set to some random stuff before the test.

But I dont know how to achieve this with Karate.

Karate allows me to create a JSON representation of my request body and define my parameters as seen below example.

    {
  "firstName": "<name>",
  "lastName": "<lastName>",
  "email": "<email>",
  "role": <role>
  }

Then in every test I have to fill all the fields with some data.

 |token    |value|
  |name     |'canberk'|
  |lastName |''|
  |email    |'[email protected]'|
  |role     |'1'|

and

|token    |value|
      |name     |''|
      |lastName |'akduygu'|
      |email    |'[email protected]'|
      |role     |'1'|

It goes on like this.

It's ok with a 4 fields JSON body but when the body starts to have more than 20 fields, it become a pain to initialise every field for every test.

Does Karate have a way of achieving this problem with a predefined steps of I need to come up with a solution?


Solution 1:

There are advantages and downside of both tools of course.

I'm definitely biased, but IMHO the only disadvantage of Karate compared to REST-assured is that you don't get compile time safety :) I hope that you have seen this comparison.

Karate has multiple ways to do what you want. Here's what I would do.

  1. create a JSON file that has all your "happy path" values set
  2. use the read() syntax to load the file (which means this is re-usable across multiple tests)
  3. use the set keyword to update only the field for your scenario or negative test

You can get even more fancier if you use embedded expressions.

  1. create a JSON file that has all your "happy path" values set and the values you want to vary look like foo: '##(foo)'
  2. before using read() you init some variables for e.g. * def foo = 'bar' and if you use null that JSON key will even be removed from the JSON
  3. read() the JSON. it is ready for use !

You can refer to this file that demonstrates some of these concepts for XML, and you may get more ideas: xml.feature