The Spy Who Loved Me

Matt Holland
2 min readJul 26, 2016

--

(With apologies to Ian Fleming)

Let’s say I have a React component that makes use of a callback to trigger some behaviour in its parent.

Q: How can we write a test to make sure that this callback is triggered correctly by the component?

A: We spy on it.

Take a look at the following test case:

it('fires an event when the first page button is clicked', () => {
let callbackFunction = (page) => { /* do nothing */ };
let spy = chai.spy(callbackFunction)

let pagination = TestUtils.renderIntoDocument(
<Pagination
currentPage={5}
onPageSelect={spy}/>);
let first = TestUtils.findRenderedDOMComponentWithClass(pagination, 'first'); TestUtils.Simulate.click(first); expect(spy).to.have.been.called.once();
expect(spy).to.have.been.called.with(1);
});

Here we have a React component (In this example it’s a pager control) under test that has as one of its props a callback function “onPageSelect”. We’re using the Chai assertion library.

The spy (created with the call to chai.spy) essentially wraps some unit of code (A function or an object) and keeps some information about how it’s being used (It then typically calls the wrapped function). In this case the object we’re wrapping is itself another test concept — a “stub”. We’re not interested in the behaviour of this function itself, so we don’t define anything within it. After instantiating the component with TestUtils.renderIntoDocument() we then use TestUtils.Simulate to interact with it — click() simulates a mouse click on the referenced element.

Once this is done we can verify that our expectations were met with a couple of standard calls to the chai expect() function. First we make sure it has been called — once only, and then verify the parameters passed were as expected.

In order to use the spy library we first need to set it up (It’s a plugin to the Chai testing library). Add it to your project:

npm install --save-dev chai-spies

Then, at the top of the test suite, we add some code like this to let Chai know about the plugin:

import chai, {expect} from 'chai';
import spies from 'chai-spies';
chai.use(spies)

It’s well worth checking out the documentation for React TestUtils (https://facebook.github.io/react/docs/test-utils.html) as well as the Chai Spies library (http://chaijs.com/plugins/chai-spies).

--

--

Matt Holland

I’m a software developer, currently specializing in the front end with JavaScript and React.