0

I'm using the should.js framework (v8.2.x) to unit test and have been playing around with some very basic tests. However, I ran into this issue with the tests failing, which has stumped me.

I defined this dummy function to test, add:

var add = function(a, b) {
  if (isNaN(a) || isNaN(b)) {
    throw new Error('One of the arguments is not a number');
  }
  return +a + +b
};

Now here're my dummy tests:

should.equal(add('1', '1'), '2');   // passes
add('1', '1').should.equal('2')     // fails!

Now according to their github, should(something) and something.should usually return the same thing, but there's no additional info on the differences.

According to their API documentation, should.equal is the same as assert.equal. But this test passes for me:

assert.equal(add('1','1'), '2'); // passes

So I have three questions:

  1. Why does add('1', '1').should.equal('2') not pass?
  2. Why are the two usages of should yielding different results?
  3. Why do the docs say should.equals is the same as assert.equals when they actually have different behavior?
  • 1
    I'm guessing that one is using `==` and the other is using `===`. The `add` function is returning a `Number`, which you're comparing to a `string`. Perhaps the type coercion being done is different? What happens if you do `add('1', '1').should.equal(2)` instead? – Chris Tavares Mar 06 '16 at 23:56
  • What @ChrisTavares said, whenever you deal with testing numbers vs strings you've gotta check how the testing is performed, I would have assumed the test would return `'11'` for `'1' + '1'` but clearly it's not very literal. – 8eecf0d2 Mar 07 '16 at 00:16
  • @ChrisTavares Yes, the `equals` should use `==`, and `1 == '1'` in javascript. There's also `strictEquals` which uses `===`. `add('1', '1').should.equal(2)` does pass. @brod If you look at `add`, I'm using the unary `+` operator to coerce them into Numbers.= – a-krisch Mar 07 '16 at 01:03
  • Are you sure about that? Check the docs & source code. The fact that `.should.equal(2)` passes seems to indicate that it's doing strict equality checking. – Chris Tavares Mar 07 '16 at 06:34
  • Exactly my issue... The docs also say that `should.equal` is the same as `assert.equal`, which I've tested to be utnrue. – a-krisch Mar 07 '16 at 07:29

1 Answers1

0

Answering your questions and what you got wrong.

Now according to their github, should(something) and something.should usually return the same thing, but there's no additional info on the differences.

should(something) and something.should yes usually the same. But you used should.equal, docs says nothing about its equallity to other methods. It is just copy of node.js own assert.equal

Why does add('1', '1').should.equal('2') not pass?

Because docs clearly said it uses === internally.

Why are the two usages of should yielding different results?

Because that is different methods, and nowhere said it should be equal.

Why do the docs say should.equals is the same as assert.equals when they actually have different behavior?

$ node
> var should = require('.')
undefined
> var assert = require('assert')
undefined
> var add = function(a, b) {
...   if (isNaN(a) || isNaN(b)) {
.....     throw new Error('One of the arguments is not a number');
.....   }
...   return +a + +b
... };
undefined
> should.equal(add('1', '1'), '2');
undefined
> assert.equal(add('1', '1'), '2');
undefined

So to try clear what you got wrong: in should.js exists should.equal(a, b) which is the same as assert.equal. Also exists something.should.equal(other) which uses === internally (because exists .eql which do deep equal check), also should(somethng).equal(other) is the same as something.should.equal(other) (but not for standard wrappers).

Hope it will make it clear.

den bardadym
  • 2,747
  • 3
  • 25
  • 27