How to get value from key response?

Hi,
Someone can please help me to write the test to get the value inside variable description?

This is my response:

{
    "key1": value1,
    "**description**": "text with id **ID** is already deprecated."
}

The value of the ID changes every time and to be updated I saved it in a variable “id_to_operate” , this is the test I tried written, but obviously it doesn’t work:

const jsonData = pm.response.json();

pm.test("Check value description", () => {
   pm.expect(jsonData.description).to.eql("text with id  " + {id_to_operate} + " is already deprecated.");

});

Could you help me?
Thank you

Hey @Paciccia :wave:

Welcome to the Postman Community! :postman:

You could split the string using the spaces as a seperator, that would return an array of values and you can select the index for the ID:

let jsonData = {
    "key1": 'value1',
    "description": "text with id **ID** is already deprecated."
}

console.log(jsonData.description.split(' ')[3]);
pm.environment.set('id_to_operate', jsonData.description.split(' ')[3]);

That’s going to work if the sentence in the description never changes but it would fail it anyone were to change it.

Is the ID returned in a specific format? You could use regex if it were in a known format, to extract it from the value.

I can see two potential issues.

  1. Does the description actually include the **'s.

If so, then these are special characters and the targeting of that element using dot notation will fail. (Please see my example code below for a work around\alternative method for targeting the element).

  1. I’m not sure how you have stored your id_to_operate, but that is not how you work with variables in scripts.

Using variables in Scripts| Postman Learning Center

The following should work.

const response = pm.response.json()

let id = pm.collectionVariables.get("id_to_operate")

let expectedResult = "text with id " + id + " is already deprecated."
console.log(expectedResult)

let actualResult = response["**description**"]
console.log(actualResult);

pm.test(`description check for ID ${id}`, () => {
    pm.expect(actualResult).to.eql(expectedResult);
})

When things fail, its useful to include the failure message, as that tells you a lot about what is failing. Although in this case, it potentially may have multiple issues.

I believe the ** was more to show/highlight which part they were trying to target :thinking:

I wasn’t sure. You would hope that developers would stay away from special characters in their JSON responses (but you never know). :face_with_raised_eyebrow:

I guess a key aspect is to use the console log.

Define the expected and actual results as separate variables and console log them. It makes it much easier to troubleshoot, particular if you are quite new to Postman or JavaScript in general.

Hi @michaelderekjones :wave:

The ** symbols are my mistake, as @danny-dainton wrote, they were in fact for show/ highlight.

However I would like to understand/know how I can compare the text inside the key-variable " description" with what the expected result should really be.

Hi @danny-dainton :slight_smile: :wave: ,

thank you for your welcome and for your reply.

I would simply like to know how I can compare the actual result with the expected result

Was there anything in @michaelderekjones’s response, that helps you compare these responses?

@danny-dainton

This is another example what I try to do:
This is the response:

{ 
   "code": 400,
  "description": "Cannot create 'xxx' without 'xxx' "
}

with the POST request I am trying to create something but with a body missing a key-value.
This is the correct response I get, but I would like to create a test that compares the value every time I try to create something without this key-value I get this description.

This is my Test: (of course the second test “fails”)

pm.test("Validate response code 400", function () {
    pm.response.to.have.status(400);
      
});

const jsonData = pm.response.json();

pm.test("Check response description is as defined", () => {
    pm.expect(jsonData).to.be.an("object");
    pm.expect(jsonData.length).to.be.greaterThan(0);
    jsonData.forEach(function (entry) {
       
        pm.expect(entry).to.have.property("description");
        pm.expect(entry.description).to.be.a("string");
        pm.expect(entry.description).to.equals("Cannot create 'xxx' without 'xxx'");
     });
});

I’m not sure why you would need to use forEach() here - Is it returning an array of objects?

Wouldn’t that work?

pm.test("Validate response code 400", function () {
    pm.response.to.have.status(400);
      
});

const jsonData = pm.response.json();

pm.test("Check response description is as defined", () => {
    pm.expect(jsonData).to.be.an("object");
    pm.expect(jsonData.length).to.be.greaterThan(0);
    pm.expect(jsonData).to.have.property("description");
    pm.expect(jsonData.description).to.be.a("string");
    pm.expect(jsonData.description).to.equal("Cannot create 'xxx' without 'xxx'");
});
1 Like

Ciao @danny-dainton

That’s right, the loop was not necessary at all.
I came to the same conclusion too, only I inputted this: “.to.contain”.

pm.expect(jsonData.description).to.contain("Cannot create ‘xxx’ without ‘xxx’ ");

Are there differences/conflicts if I leave “.to.contain”? or is it preferable to insert “equal”?

Thank you very much for your support, it was very helpful! :slight_smile:

1 Like

This all depends on the type of assertion that you want in that test:

  • equal would be need to match that exactly or it’s going to fail.
  • contains would be slightly more flexible but could introduce other issues, if the description contains that string but also something that shouldn’t be in there - That would still pass the test. :grimacing:
1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.