How to resolve "Cannot read property 'should' of undefined" in chai?

BattleFrog picture BattleFrog · May 15, 2017 · Viewed 15.7k times · Source

I'm trying to test my test my RESTful nodejs API but keep running into the following error.

Uncaught TypeError: Cannot read property 'should' of undefined

I'm using the restify framework for my API.

'use strict';

const mongoose = require('mongoose');
const Customer = require('../src/models/customerSchema');

const chai = require('chai');
const chaiHttp = require('chai-http');
const server = require('../src/app');
const should = chai.should();

chai.use(chaiHttp);

describe('Customers', () => {
   describe('/getCustomers', () => {
       it('it should GET all the customers', (done) => {
           chai.request(server)
               .get('/getCustomers')
               .end((err, res) => {
                   res.should.have.status(200);
                   res.body.should.be.a('array');
                   done();
                });
       });
   });
});

The testing works fine when I remove the line res.body.should.be.a('array'); Is there anyway I can fix this problem?

Answer

Qix - MONICA WAS MISTREATED picture Qix - MONICA WAS MISTREATED · May 15, 2017

Normally, when you suspect a value might be undefined or null, you would wrap the value in a call to should(), e.g. should(res.body), since referencing any property on null or undefined results in an exception.

However, Chai uses an old version of should that doesn't support this, so you need to assert the existence of the value beforehand.

Instead, add one more assertion:

should.exist(res.body);
res.body.should.be.a('array');

Chai uses an old/outdated version of should, so the usual should(x).be.a('array') won't work.


Alternatively, you can use the official should package directly:

$ npm install --save-dev should

and use it as a drop-in replacement:

const should = require('should');

should(res.body).be.a('array');