Viet
Viet

Reputation: 6953

npm chai check returned object has property

I'm trying to test my Promise with chai. My promise returns an array of objects like this:

[
  {id: 1, Location: 'some where'},
  {id: 2, Location: 'over the rainbow'},
]

I keep getting this error but my test still passes:

UnhandledPromiseRejectionWarning: AssertionError: expected [ Array(7) ] to have deep property 'Location'

My code:

describe('Function myPromise', () => {
    it(`should returns object with property Location`, () => {
       expect(myPromise(myParams)).to.eventually.have.deep.property('Location');
    });
});

I've also tried:

to.eventually.have.deep.property.include('Location');
to.eventually.have.property('Location');
to.eventually.be.an('array').and.have.property('Location');
return expect(myPromise(myParams)).to.eventually.have('Location');

Upvotes: 2

Views: 1969

Answers (4)

Viet
Viet

Reputation: 6953

I've figured out how to avoid that error. It's simpler and more straightforward than I thought:

describe('Function myPromise', () => {
    it(`should returns object with property Location`, () => {
       myPromise(myParams)
       .then((results) => {
         expect(results).to.be.an('array');
         results.forEach((result) => {
           expect(result).to.have.property('Location');
         });
       });
    });
});

Upvotes: 2

deerawan
deerawan

Reputation: 8443

have.deep.property is applicable for checking object but seems like you checked the array.

Let me illustrate with a simple example

const fixtures = [
 {id: 1, Location: 'some where'},
 {id: 2, Location: 'over the rainbow'},
];

// I tested the first element
expect(fixtures[0]).to.have.deep.property('Location'); // passed

If you want to check every single element, you probably need a loop.

Updates

To use loop to check every element, the first thing to do is to grab the fixtures from the promise function. In this way, I'm using async/await but you can use promise too.

describe("Function myPromise", () => {
  it(`should returns object with property Location`, async () => {
    const fixtures = await myPromise(myParams); // get the fixtures first

    // looping and check each element 
    fixtures.forEach(fixture =>
      expect(fixture).to.have.deep.property("Location"); // no need to use `eventually.have.deep` 
    );
  });
});

Hope it helps

Upvotes: 2

Tom Faltesek
Tom Faltesek

Reputation: 2818

You can try using Joi (or chai-joi in your case) to make schema validation very easy. I would definitely try this if you're going to be having many tests with object schema validation.

Upvotes: 1

bitznbytez
bitznbytez

Reputation: 106

Well a promise is handled asynchronously. I believe you are missing the .then() method in which will return the promise(rejected or fulfilled).

describe('Function myPromise', () => {
    it(`should returns object with property Location`, () => {
       expect(myPromise(myParams).then(data => data).to.eventually.have.deep.property('Location');
    });
});

Upvotes: 0

Related Questions