DEV Community

Cover image for Good assertion messages with EmberJS + sinon
Michal Bryxí
Michal Bryxí

Posted on

Good assertion messages with EmberJS + sinon

Good assertion messages in tests should help you quickly figure out what went wrong in case the test goes red. Bad assertion messages on the other hand ...

90% of code comments be like a sticker saying "cat" attached to a cat

Since I work on quite a few EmberJS projects with different setups, I thought it would be a good idea to document the options.

Initial setup

For sinon in your EmberJS project, you will probably want to install ember-sinon-qunit. This will also automatically pull in ember-sinon for you.

Assertions

Let's assume following test code with some sinon usage:

import sinon from 'sinon';

test('my awesome test', function (assert) {
  const stub = sinon.stub().named('Awesome spy').returns('hello');

  stub('First call');
  stub('Second call');

  // Place for future assertions
});
Enter fullscreen mode Exit fullscreen mode

qunit

By default qunit, which is available in every ember-cli project offers assert functionality which has quite a few methods. Then those can be used to examine what our sinon object experienced:

assert.ok(spy.calledOnce);
Enter fullscreen mode Exit fullscreen mode

Which would produce following error:

failed, expected argument to be truthy, was: false

Which is ... suboptimal. The message does not give us context of why it failed. That we expected the function to be called exactly once.

We could, of course, do following:

assert.ok(stub.calledOnce, 'Expected to be called only once');
Enter fullscreen mode Exit fullscreen mode

Which would give us a nicer error:

Expected to be called only once

But this is:

  1. More work
  2. Prone to future refactoring errors

Can we do better?

ember-sinon

Thanks to ember-sinon package we can import sinon directly into our tests

sinon.assert.calledOnce(stub);
Enter fullscreen mode Exit fullscreen mode

Giving us following, slightly more informative error message:

Died on test #1: expected Awesome spy to be called once but was called twice

This is better as it gives us more context, but:

  1. One failed assertion will make your test die, not executing other assertions. Potentially hiding important information from you.
  2. Passing assertions do not count towards assertion count, so if this is the only type in your test, then you will get Expected at least one assertion, but none were run - call expect(0) to accept zero assertions. error.
  3. Because of the point above, in case you have other types of assertions, it might be confusing to know which message belongs to which assertion.

Can we do better?

qunit-sinon-assertions

Addon qunit-sinon-assertions was created exactly to address the shortcomings of the previous methods. So that this code:

assert
  .spy(stub)
  .calledOnce()
  .calledWith(['John Doe'])
  .returnedWith('world');
Enter fullscreen mode Exit fullscreen mode

Will produce following errors:

A lot of cool error messages

Conclusion

I do believe that easy-to-understand assertion messages are important. There are different methods to achieve this. Personally I prefer to write less code and lean on a convention that is provided by a tool.


Photo by Miguel Á. Padriñán

Top comments (0)