Sinon
assertions for QUnit
with custom messages support and friendly default ones.
Why not just use assert.ok(spy.calledOnce, 'spy was called')
?
- the addon provides a lot more context in case of a failing test
- it has user-friendly default messages, so you don't have to write your own in simple cases
Let's say we have this test code:
const emitStub = sinon.stub().named('emit');
emitStub('model-loaded-worng');
assert.ok(
emitStub.calledWithExactly('model-loaded'),
'emit was called with "loaded"'
);
assert.spy(emitStub).calledWithExactly(['model-loaded']);
The assert.ok
approach doesn't give you any context:
The assert.spy
provides more context:
Let's say we were lazy and didn't write custom messages:
const emitStub = sinon.stub().named('emit').returns('no way');
emitStub('model-loaded-worng');
assert.ok(emitStub.calledWithExactly('model-loaded'));
assert.ok(emitStub.returned('job is done!'));
assert
.spy(emitStub)
.calledWithExactly(['model-loaded'])
.returnedWith('job is done!');
The assert.ok
one will look like this:
The assert.spy
will be:
First, install the addon:
yarn add -D qunit-sinon-assertions
Next, import qunit-sinon-assertions
module anywhere in your tests/test-helper.js
file:
// This will make `assert.spy()` API available in your tests.
import setupSinonAssert from 'qunit-sinon-assertions';
setupSinonAssert(QUnit.assert);
It's also recommended to install ember-sinon-qunit
to get automatic sinon cleanup after each test. With both addons your config can look like this:
import Application from '../app';
import config from '../config/environment';
import * as QUnit from 'qunit';
import { setApplication } from '@ember/test-helpers';
import { setup } from 'qunit-dom';
import { start } from 'ember-qunit';
import setupSinon from 'ember-sinon-qunit';
import setupSinonAssert from 'qunit-sinon-assertions';
setApplication(Application.create(config.APP));
setupSinon();
setup(QUnit.assert);
setupSinonAssert(QUnit.assert);
start();
It's possible to chain assertions:
assert.spy(fn)
.calledTwice('should be called twice')
.calledWith([arg1, arg2], 'with these args')
.returnedWith(value);
You can use Sinon matchers with most assertions like this:
assert.spy(fn).didNotReturnWith(sinon.match({ id: 1 }));
Here is an example of using the assertions in a real project: ember-on-resize-modifier tests
Name your stand alone spies
for better error messages:
this.onResize = sinon.spy().named('onResize');
assert.spy(this.onResize).calledOnce();
// For methods it's not needed:
let obj = { method() {} };
let methodSpy = sinon.spy(obj, 'method');
Here are all available assertions (feel free to add more):
assert.spy(fn).called(message);
assert.spy(fn).notCalled(message);
assert.spy(fn).calledTimes(count, message);
assert.spy(fn).calledOnce(message);
assert.spy(fn).calledTwice(message);
assert.spy(fn).calledWith([arg1, arg2], message);
assert.spy(fn).notCalledWith([arg1, arg2], message);
assert.spy(fn).calledWithExactly([arg1, arg2], message);
assert.spy(fn).notCalledWithExactly([arg1, arg2], message);
assert.spy(fn).returnedWith(value, message);
assert.spy(fn).didNotReturnWith(value, message);
assert.spy(fn).threw(message);
assert.spy(fn).threwWith(exception, message);
assert.spy(fn).lastCalledWith([arg1, arg2], message);
assert.spy(fn).lastNotCalledWith([arg1, arg2], message);
assert.spy(fn).lastCalledWithExactly([arg1, arg2], message);
assert.spy(fn).lastNotCalledWithExactly([arg1, arg2], message);
assert.spy(fn).lastReturnedWith(value, message);
assert.spy(fn).lastDidNotReturnWith(value, message);
See the Contributing guide for details.
This project is licensed under the MIT License.