Warm tip: This article is reproduced from serverfault.com, please click

How do I partially compare deeply nested objects in Cypress assertions?

发布于 2019-08-28 17:19:35

I'm using cypress.io as my automation framework for both API and UI tests. I've written multiple API tests that are running and passing but they're only validating that the response.status returns a 200. I want to compare the response json from a GET against a stored "expected" response to confirm that the json response data is correct.

I've tried different variations of to.deep.equal and deepEquals in my .then(response => {} code block. But I don't want to validate that just one field is returning the correct value, I want to validate whether a bunch of different fields are returning the correct values. My GET request returns over 100 lines of nested json fields/values and I only want to validate 20 or so fields/values nested inside each other.

*Note: ignore revId, it's from an earlier request.

cy.request({
    method: 'GET',
    log: true,
    url: 'https://dev.api.random.com/calculators/run-calculate/524/' +
        revId,

    headers: {
        'content-type': 'application/json',
        'x-api-key': calcXApiKey
    },
    body: {}
}).then(response => {
    const respGet = response.body
    const tPrice = response.body.data.calculations.t_costs[0].comparison.t_price
    cy.log(respGet, tPrice)
    assert.deepEqual({
        tPrice
    }, {
        t_price: '359701'
    })
       // assert.equal(response.status, 200) -- This works great
})

Error= expected { tPrice: undefined } to deeply equal { t_price: 359701 }

Questioner
Chase Small
Viewed
0
dwelle 2019-08-29 20:20:27

In your example, you're comparing object { tPrice: tPrice } with { t_price: '359701' }, that's why it's always going to fail because the keys are different (apart from the fact that the tPrice variable value is undefined).

If you're already storing the actual value in a variable, there's no need to make an object out of it and use deepEqual. You can do:

const tPrice = response.body.data.calculations.t_costs[0].comparison.t_price
assert.equal(tPrice, '359701');

As to your other question, if I understand it correctly, your response looks like:

{
  data: {
    calculations: {
      t_costs: [
        { comparison: { t_price: "1111" } },
        { comparison: { t_price: "2222" } },
        { comparison: { t_price: "3333" } },
        { comparison: { t_price: "4444" } },
        /* ... */
      ]
    }
  }
}

And you want to assert just a few of those t_costs objects.

For that it's best to use a chai plugin such as debitoor/chai-subset.

To set it up:

npm install --save-dev chai-subset

In your cypress/support/index.js:

const chai = require('chai');
const chaiSubset = require('chai-subset');
chai.use(chaiSubset);

In your spec:

/* ... */
expect( response.body.data.calculations.t_costs )
    .to.containSubset([
        { comparison: { t_price: "1111" } },
        { comparison: { t_price: "3333" } }
    ]);