jest.mock('utils/Namespacing');
import React from 'react';
import ColorDot from '../ColorDot';
import { shallow } from 'enzyme';
const defaultProps = { color: 'red' };
const renderColorDot = newProps => {
const props = { ...defaultProps, ...newProps };
return shallow(<ColorDot {...props} />);
};
describe('ColorDot', () => {
let colorDot;
describe('with a child', () => {
beforeEach(() => {
colorDot = renderColorDot({ children: <div>Content</div> });
});
it('matches snapshot', () => {
expect(colorDot).toMatchSnapshot();
});
});
});link to testing trophy/strategy docs define the purpose of unit tests and why we write them
Clone picante, npm run deps npm run test:unit to run all the tests.
Create __unit__ folder as a sibling of the file you want to test. If you're testing src/Doubler.js you then want to create a src/__unit__/Doubler.spec.js . This file must be in a folder called __unit__ and end in .spec.js in order to be ran by jest.
If you have a function like so
// src/Doubler.js
const Doubler = number => number * 2;
export default Doubler;then you might have a test that looks like
// src/__unit__/Doubler.spec.js
import doubler from '../Doubler';
describe('Doubler', () => {
it('doubles', () => {
expect(doubler(2)).toBe(4);
});
});npm run test:unit runs jest. This means you can give this command any option you can give jest, as long as all the options are after a -- (see more here)
... include stuff from first pass (pattern matching, —watch)
See here for using debuggers in your test Jest Debugging
One tool that we have found especially useful is the vscode-jest plugin. Install Github
In most of our unit tests, we arrange, act, then assert.
import doubler from '../Doubler';
it('works', () => {
const input = 2; // Arrange
const result = doubler(input) // Act
expect(result).toBe(4); //Assert
}) In this case, AAA may be a bit overkill. Maybe let’s make a better example?
describe('doubler', () => {
describe('with 2', () => {
beforeEach(() => {
result = doubler(2);
});
it('works', () => {
expect(result).toBe(4);
});
});
});jest.mock is used to mock functions that our units depend on. jest.mock('../SomeFile') makes it so that the SomeFile file is never used, and everything imported it is a function that returns undefined. you can give jest.mock a second arg to return an object that replaces the module. Typically we will set the mocked functions to the stub jest.fn() so that if we need to change their return value, we can do something like this:
jest.mock('../SomeFile', () => ({
isLoading: jest.fn(),
}));
import { isLoading } from '../SomeFile';
describe('Thing', () => {
describe('when content is loading', () => {
beforeEach(() => {
isLoading.mockReturnValue(true);
});
});
describe('when content is loaded', () => {
beforeEach(() => {
isLoading.mockReturnValue(false);
});
});
});if we don't want to change the mockReturnValue for the sake of the test, we can mock a module like such:
jest.mock('../SomeFile', () => ({
isLoading: jest.fn(() => false),
});
...With jest.mock if there is no second arg given, it uses the mock defined
When using jest.mock, it mocks the whole module. So if you are seeing a function that should be mocked is returning undefined, then you will need to supply your own implementation or mockReturnValue.
Since jest runs each test in its own process, we should bias towards making multiple assertions on the same state inside an it block instead of two.
const name = 'Sam';
const modd = 'happy';
const getPerson = () => ({
name,
mood,
});
describe('an object', () => {
let person;
beforeEach(() => {
person = getPerson();
});
// Bad
it('has name', () => {
expect(person.name).toBe(name);
});
it('has mood', () => {
expect(person.mood).toBe(mood);
});
// Good
it('has properties', () => {
expect(person.name).toBe(name);
expect(person.mood).toBe(mood);
});
});Jest Snapshot testing docs
The first time jest snapshot tests are ran it will save (and create) the snapshot in a __snapshots__ folder next to the spec comparing against the snapshot. Then every output of the snapshot will be compared to the saved intended snapshot. If your snapshot changes, and you wish to update it, jest will prompt you when running the tests, in this case you press u.
When testing a react component, an ideal scenario is to take snapshots of the component with different expected props, and stubbing out functions that may cause side effects and assert they should have been called.
import { OurCustomButton } from '../OurCustomButton';
import { shallow } from 'enzyme';
const defaultProps = {
disabled: false,
onClick: jest.fn(),
};
const renderButton = newProps => {
const props = {...defaultProps, ...newProps};
return shallow(<OurCustomButton {...props} />);
};
describe('OurCustomButton', () => {
let button;
describe('when disabled', () => {
beforeEach(() => {
button = renderButton({ disabled: true });
});
it('is disabled', () => {
expect(button).toMatchSnapshot();
});
});
describe('when enabled', () => {
beforeEach(() => {
button = renderButton();
});
it('is enabled', () => {
expect(button).toMatchSnapshot();
});
describe('after clicking', () => {
beforeEach(() => {
button.simulate('click');
});
it('calls onClick', () => {
expect(defaultProps.onClick).toHaveBeenCalled();
});
});
});
});In unit tests we want to shallow render.
We probably don't want to do this.