What is the difference between assert
, expect
and should
, and when to use what?
assert.equal(3, '3', '== coerces values to strings');
var foo = 'bar';
expect(foo).to.equal('bar');
foo.should.equal('bar');
What is the difference between assert
, expect
and should
, and when to use what?
assert.equal(3, '3', '== coerces values to strings');
var foo = 'bar';
expect(foo).to.equal('bar');
foo.should.equal('bar');
I hope this simple examples makes their differences clear
Assert
In all cases, the assert style allows you to include an optional message as the last parameter in the assert statement. These will be included in the error messages should your assertion not pass.
Note expect and should uses chainable language to construct assertions, but they differ in the way an assertion is initially constructed. In the case of should, there are also some caveats and additional tools to overcome the caveats.
Expect
Expect allows you to include arbitrary messages to prepend to any failed assertions that might occur.
This comes in handy when being used with non-descript topics such as booleans or numbers.
Should
The should style allows for the same chainable assertions as the expect interface, however it extends each object with a should property to start your chain. This style has some issues when used with Internet Explorer, so be aware of browser compatibility.
Differences between expect and should
First of all, notice that the expect require is just a reference to the expect function, whereas with the should require, the function is being executed.
The expect interface provides a function as a starting point for chaining your language assertions. It works on node.js and in all browsers.
The should interface extends Object.prototype to provide a single getter as the starting point for your language assertions. It works on node.js and in all modern browsers except Internet Explorer.
The differences are documented there.
The three interfaces present different styles of performing assertions. Ultimately, they perform the same task. Some users prefer one style over the other. This being said, there are also a couple technical considerations worth highlighting:
The assert and expect interfaces do not modify
Object.prototype
, whereas should does. So they are a better choice in an environment where you cannot or do not want to changeObject.prototype
.The assert and expect interfaces support custom messages just about everywhere. For instance:
The message "foo should be true" will be output together with the failed assertion if the assertion fails. You don't get the opportunity to set a custom message with the should interface.
(Historical note: for a long time this answer stated that to get a custom message with
expect
, you'd have to use a workaround. Aurélien Ribon informed me that passing a message toexpect
as a second parameter works. Consequently, there is no need for a workaround. I've not been able to find which version of Mocha started providing support for this message, nor have I been able to find which version of the documentation documented it for the first time.)Note that
assert.isTrue(foo)
,expect(foo).to.be.true
andfoo.should.be.true
all output the following if you do not use a custom message, andfoo === 1
:So while the expect and should interface are nicer to read, it is not like one interface is more naturally informative than the other when an assertion fails. This message, which is identical for all three interfaces, does not tell you what exactly you were testing, only that the value you got was
1
but you wantedtrue
. If you want to know what you were testing, you need to add a message.