DieGraueEminenz
DieGraueEminenz

Reputation: 880

How to test for absence of (potentially) nested JSON properties in Postman?

I want to test for absence of the nested property "x"

The test must fail if, the response looks like this

A:

{
    "first": 1,
    "second": {
        "one": 1,
        "two": 2,
        "three": {
            "x": 1,
            "y": 2
        }
    }
}

But for the following examples it must pass:

B:

{
    "first": 1,
    "second": {
        "one": 1,
        "two": 2,
        "three": {
            "y": 2
        }
    }
}

C:

{
    "first": 1,
    "second": {
        "one": 1,
        "two": 2
    }
}

D:

{
    "first": 1
}

Of course. I can use pm.expect(object).to.not.have.property("x") to test for the absence. But this wouldn't be helpful in all cases.

For example, my PostMan test-code:

pm.test("(nested)property 'x' not available", function () {
    var jsonData = pm.response.json();
    pm.expect(jsonData.second.three).to.not.have.property("x")
});

would work great for the cases A and B, but not for C and D, because the parents "second" or "three" of the property can be undefined. But i dont want to test for the absence of them, because its not the target of this specific test.

Is there any BDD Chai function, that delivers this functionality or am i forced to implement a recursive helper function for this case?

Upvotes: 3

Views: 1696

Answers (3)

DieGraueEminenz
DieGraueEminenz

Reputation: 880

My final solution:

var a = {
    "first": 1,
    "second": {
        "one": 1,
        "two": 2,
        "three": {
            "x": 1,
            "y": 2
        }
    }
};

var b = {
    "first": 1,
    "second": {
        "one": 1,
        "two": 2,
        "three": {
            "y": 2
        }
    }
};

var c = {
    "first": 1,
    "second": {
        "one": 1,
        "two": 2
    }
};

var d = {
    "first": 1
};


pm.test("(nested)property 'x' NOT available in 'a'", function () { //must fail for a
    var jsonData = a;
    pm.expect(_.get(jsonData, "second.three.x", undefined)).to.be.undefined;
});

pm.test("(nested)property 'x' NOT available in 'b'", function () {
    var jsonData = b;
    pm.expect(_.get(jsonData, "second.three.x", undefined)).to.be.undefined;
});

pm.test("(nested)property 'x' NOT available in 'c'", function () {
    var jsonData = c;
    pm.expect(_.get(jsonData, "second.three.x", undefined)).to.be.undefined;
});

pm.test("(nested)property 'x' NOT available in 'd'", function () {
    var jsonData = d;
    pm.expect(_.get(jsonData, "second.three.x", undefined)).to.be.undefined;
});

Upvotes: 0

Danny Dainton
Danny Dainton

Reputation: 25881

You can make use of the inbuilt Lodash functions to breakdown the data more, rather than trying to do it all in the pm.expect() statement.

The _.get() function might be a useful one to explore that with - https://lodash.com/docs/4.17.11#get

Upvotes: 1

holydragon
holydragon

Reputation: 6728

This is not exactly what you are looking for but I hope it may be somehow useful for anyone interested.

First, stringify the JSON into a string and then search for the keyword with its enclosing double quotes to precisely looking for the exact word (the property it is).

Of course, this is just a concept but I think it can be an option for you to give it a try if all else fails.

There are rooms for improvement, I see. So, feel free to adjust it if you need to.

const cases = [{
    "first": 1,
    "second": {
      "one": 1,
      "two": 2,
      "three": {
        "x": 1,
        "y": 2
      }
    }
  },
  {
    "first": 1,
    "second": {
      "one": 1,
      "two": 2,
      "three": {
        "y": 2
      }
    }
  },
  {
    "first": 1,
    "second": {
      "one": 1,
      "two": 2
    }
  },
  {
    "first": 1,
    "example": "notx"
  }
]
const property = "x" // Property that you are looking for its absence
cases.forEach(c => {
  console.log(JSON.stringify(c).includes('"' + property + '"'))
  // True = property is present | False = property is absent
})

Upvotes: 0

Related Questions