Guidelines for testing React components

Why write tests?

To prove your code works

describe('MyList', () => {
test(
'should sort alphabetically when the "name" header is clicked'
)
})
describe('An admin', () => {
describe('with no teams', () => {
test('should see the empty teams page')
test('should see the New Team button')
})
describe('with existing teams', () => {
test('should a list of teams')
})
})

To protect code from breaking when you work on it

import Header from "./Header";it("should render signed out by default", () => {
expect.assertions(2)
const tree = mount(<Header />);
const markers = {
in: tree.find({"data-test": "signedin"}),
out: tree.find({"data-test": "signedout"})
};
expect(markers.in).toHaveLength(0);
expect(markers.out).toHaveLength(1);

});

To document behavior

describe('Component states', () => {
test("loading state snapshot should match", () => {
const snap = shallow(<Foo loading />);
expect(snap).toMatchSnapshot();
});
test("empty state snapshot should match", () => {
const snap = shallow(<Foo items={[]} />);
expect(snap).toMatchSnapshot();
});
it("happy path state snapshot should match", () => {
const snap = shallow(<Foo items={dummyItemsList} />);
expect(snap).toMatchSnapshot();
});
it("error state snapshot should match", () => {
const snap = shallow(<Foo items={dummyInvalidItemsList} />);
expect(snap).toMatchSnapshot();
});
})

To help make design decisions

Testing React

Recommended Libraries

yarn add --dev jest react-testing-library sinon
// importing renderers for snapshotting and DOM assertions
import { render } from "react-testing-library";

Snapshots vs Assertions

“Black Box” Testing

Testing Async Code

Callback style with done
it("should get item from API", done => {
expect.assertions(1) // ⚠️
fetch('/url/1')
.then(data => expect(data).toHaveLength(1); done)
.catch(err => done)
})
Returning a Promise
it("should get item from API", () => {
return fetch('/url/1')
.then(data => expect(data).toHaveLength(1))
})
Using async/await syntax with Promises
it("should get item from API", async () => {
const data = await fetch('/url/1')
expect(data).toHaveLength(1)
})
Testing error handling with async/await
it("should not get item when unauthorized", async () => {
expect.assertions(1) // ⚠️
try {
const data = await fetch('/url/2')
} catch(err) {
expect(err.message).toEqual('Not Authorized')
}
})

Testing Library Code

Quotes About Testing

What Every Unit Test Needs (Eric Elliot)

Tautological Tests (Randy Coulman)

Behavior-Driven Development (Wikipedia)