Chai: how to test for undefined with 'should' syntax

JavascriptAngularjsTestingChai

Javascript Problem Overview


Building on this tutorial testing an angularjs app with chai, I want to add a test for an undefined value using the "should" style. This fails:

it ('cannot play outside the board', function() {
  scope.play(10).should.be.undefined;
});

with error "TypeError: Cannot read property 'should' of undefined", but the test passes with the "expect" style:

it ('cannot play outside the board', function() {
  chai.expect(scope.play(10)).to.be.undefined;
});

How can I get it working with "should"?

Javascript Solutions


Solution 1 - Javascript

This is one of the disadvantages of the should syntax. It works by adding the should property to all objects, but if a return value or variable value is undefined, there isn't a object to hold the property.

The documentation gives some workarounds, for example:

var should = require('chai').should();
db.get(1234, function (err, doc) {
  should.not.exist(err);
  should.exist(doc);
  doc.should.be.an('object');
});

Solution 2 - Javascript

should.equal(testedValue, undefined);

as mentioned in chai documentation

Solution 3 - Javascript

(typeof scope.play(10)).should.equal('undefined');

Solution 4 - Javascript

Test for undefined

var should = require('should');
...
should(scope.play(10)).be.undefined;

Test for null

var should = require('should');
...
should(scope.play(10)).be.null;

Test for falsy, i.e. treated as false in conditions

var should = require('should');
...
should(scope.play(10)).not.be.ok;

Solution 5 - Javascript

I struggled to write the should statement for undefined tests. The following doesn't work.

target.should.be.undefined();

I found the following solutions.

(target === undefined).should.be.true()

if can also write it as a type check

(typeof target).should.be.equal('undefined');

Not sure if the above is the right way, but it does work.

According to Post from ghost in github

Solution 6 - Javascript

Try this:

it ('cannot play outside the board', function() {
   expect(scope.play(10)).to.be.undefined; // undefined
   expect(scope.play(10)).to.not.be.undefined; // or not
});

Solution 7 - Javascript

Don't forget about a combination of have and not keywords:

const chai = require('chai');
chai.should();
// ...
userData.should.not.have.property('passwordHash');

Solution 8 - Javascript

The answer by @david-norman is correct as per the documentation, I had a few issues with setup and instead opted for the following.

(typeof scope.play(10)).should.be.undefined;

Solution 9 - Javascript

You can wrap your function result in should() and test for a type of "undefined":

it ('cannot play outside the board', function() {
  should(scope.play(10)).be.type('undefined');
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionthebenedictView Question on Stackoverflow
Solution 1 - JavascriptDavid NormanView Answer on Stackoverflow
Solution 2 - JavascriptdanielView Answer on Stackoverflow
Solution 3 - JavascriptteddychanView Answer on Stackoverflow
Solution 4 - JavascriptPeter DotchevView Answer on Stackoverflow
Solution 5 - JavascriptVirathsView Answer on Stackoverflow
Solution 6 - JavascriptEpokKView Answer on Stackoverflow
Solution 7 - JavascriptYarovoyView Answer on Stackoverflow
Solution 8 - JavascriptAndy PolhillView Answer on Stackoverflow
Solution 9 - JavascriptpegliView Answer on Stackoverflow