Chai: how to test for undefined with 'should' syntax
JavascriptAngularjsTestingChaiJavascript 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.
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');
});