- When given some input, does the output look like
x
? - Runs quickly
- Contained to a single unit of code (e.g. a function)
- Written by developers, unlike acceptance tests
- Touches the database
- Makes network requests (to APIs)
- Touches the file system
- It can't run at the same time as other unit tests
- It has to run in a certain order
- Jest (https://facebook.github.io/jest)
- Test runner
- Test blocks (e.g.
describe
andit
) - Assertions (e.g.
expect(1 + 2).toEqual(3)
) Snapshot testing
- Enzyme (https://github.com/airbnb/enzyme)
- Shallow rendering
- Inspecting component trees
Discuss this
describe('<Button />', () => {
it('should invoke the onClick callback when clicked');
});
Behaviour driven development feels better suited to UI based testing rather than just functional definitions.
const Button = ({
onClick,
text
}) => (
<div onClick={onClick} className="button">
{text}
</div>
)
// Implementation details inside tests
it('should return a <div />', () => {
const tree = shallow(<Button text="Hello World" />);
expect(tree.type()).toEqual('div');
});
it('should show passed text in .button', () => {
const tree = shallow(<Button text="Hello World" />);
const actual = tree.find('.button').text();
expect(actual).toEqual('Hello World');
});
it('should display the passed text prop', () => {
const tree = shallow(<Button text="Hello World" />);
expect(tree.text).toContain("Hello World");
});
it('should invoke onClick prop when clicked', () => {
const spy = jest.fn();
const tree = shallow(
<Button
text="Hello World
onClick={spy} />
);
tree.simulate('click');
expect(spy.calls).toEqual(1);
});
- Does not create DOM nodes
- Returns objects describing your component tree
- Does not render components outside the boundary of your component under test
wrapper.simulate('click')
will look for theonClick
prop and invoke that- This means that it will invoke just the callback provided for that prop
- Simulating events does not trigger with an Event
- You must provide an object if you want it:
wrapper.simulate('click', { id: 123 });
- You must provide an object if you want it:
This is a more complex component tree
const SeatPrefs = ({ willReserve: boolean }) => (
<div>
<h3>Seating Preferences</h3>
{ willReserve && <div>
<SeatSelections />
<SeatLocations />
<SmallNote />
</div> }
</div>
);
it('should render a Direction selectbox');
it('should render a Position selectbox');
it('should render a CoachType selectbox');
it('should render a Table seat checkbox');
it('should render a Power Socket checkbox');
it('should render a Luggage Rack checkbox');
it('should render a Near Toilet checkbox');
😀
it('should render <SeatSelections /> when willReserve');
it('should render <SeatLocations /> when willReserve');
it('should render <SmallNote /> when willReserve');