Demonstrates Mocha, Chai, Sinon, and Istanbul
Run these commands:
yarn
yarn test-cov
Observe this output:
keyDown
✓ returns a function
✓ that function returns expected boolean
✓ that function calls given dispatch
Dispatcher v1
✓ Dispatches a keyDown event with the specified keyCode if the selected element is not an <input>
Dispatcher v2
with non-<input>
✓ dispatches key
✓ calls keyDown with only keyCode as argument
with <input>
✓ does not dispatch key
✓ does not call keyDown
event.preventDefault
✓ called when dispatch returns true
✓ does not call preventDefault when dispatch returns false
10 passing (48ms)
=============================================================================
Writing coverage object [/Users/tony/src/tmp/mocha-test-demo/coverage/coverage.json]
Writing coverage reports at [/Users/tony/src/tmp/mocha-test-demo/coverage]
=============================================================================
=============================== Coverage summary ===============================
Statements : 100% ( 16/16 )
Branches : 100% ( 4/4 )
Functions : 100% ( 5/5 )
Lines : 100% ( 12/12 )
================================================================================
✨ Done in 1.89s.
Given the following functions, how would dispatch()
be unit tested?
export const keyDown = key => (dispatch, getState) => {
const { modifier } = getState().data;
dispatch({ type: KEYDOWN, key });
return handle(modifier, key); // Returns true or false
};
export const mapDispatchToProps = dispatch => ({
onKeyDown: e => {
if(e.target.tagName === "INPUT") return;
const handledKey = dispatch(keyDown(e.keyCode));
if(handledKey) {
e.preventDefault();
}
}
});
http://stackoverflow.com/q/41633297/6277151
Our goal is to verify:
- The key-event handler exits early when the target is an
<input>
. Otherwise, the following occurs. dispatch()
is called.- The call to
dispatch()
has exactly one argument: a functionF
. F
is the return value ofkeyDown()
.keyDown()
is called.- The call to
keyDown()
has exactly one argument: the key code.
Since keyDown()
is imported from actions
, we could stub
the function in order to observe its calls and arguments and
to set its return value. In our case, we setup keyDown()
to return
a dummy
value whenever it gets called with keyCode
:
before(() => {
keyDown = stub(actions, "keyDown");
keyDown.withArgs(keyCode).returns(dummy);
});
After our tests are done, we need to undo the stub in case other test suites need to use it.
after(() => {
keyDown.restore();
});
Then, our unit test would verify dispatch
was called with the dummy
that we had previously setup. We know the dummy
can only be returned
by our stubbed keyDown()
, so this check also verifies that keyDown()
was called.
expect(dispatch).to.have.been.calledWith(dummy);
And this is a more explicit check that keyDown()
was called with the
keyCode
as its only argument:
expect(keyDown).to.have.been.calledWithExactly(keyCode);
MIT © Anthony Trinh