Skip to content

Instantly share code, notes, and snippets.

@dgowrie
Last active September 19, 2018 05:27
Show Gist options
  • Select an option

  • Save dgowrie/146b68ef5754d617973506bb7eace57c to your computer and use it in GitHub Desktop.

Select an option

Save dgowrie/146b68ef5754d617973506bb7eace57c to your computer and use it in GitHub Desktop.
Sublime Text Snippet: Unit Test - React Component with Enzyme
<snippet>
<content><![CDATA[
/**
* Boilerplate and "right way to test" examples:
* https://medium.freecodecamp.org/the-right-way-to-test-react-components-548a4736ab22
*/
import React from 'react';
import { mount, shallow } from 'enzyme';
import ${1:${TM_FILENAME/(.+)\..+|.*/$1/:ComponentUnderTest}} from './${1:${TM_FILENAME/(.+)\..+|.*/$1/:ComponentUnderTest}}';
import ${3:ChildComponent} from './${3:ChildComponent}';
describe('<${1:${TM_FILENAME/(.+)\..+|.*/$1/:ComponentUnderTest}} />', () => {
/* eslint-disable react/jsx-filename-extension */
let defaultProps;
let componentUnderTest;
/**
* Shallow rendering of the component under test
* @see https://airbnb.io/enzyme/docs/api/shallow.html
*
* Always begin with shallow
* As of Enzyme v3, the shallow API does call React lifecycle methods componentDidMount and componentDidUpdate
* Useful to:
* - constrain yourself to testing a component as a unit
* - ensure that your tests aren't indirectly asserting on behavior of child components
*/
let shallowRenderCUT;
const renderComponentUnderTest = (props) => {
if (!shallowRenderCUT) {
shallowRenderCUT = shallow(<${1:${TM_FILENAME/(.+)\..+|.*/$1/:ComponentUnderTest}} {...props} />);
}
return shallowRenderCUT;
};
/**
* Full DOM rendering ("mount") of the component under test, including child components
* @see https://airbnb.io/enzyme/docs/api/mount.html
*
* Ideal for use cases where testing:
* - components that may interact with DOM APIs
* - components that are wrapped in higher order components
* - component lifecycle methods other than componentDidMount and componentDidUpdate and/or children behavior
*/
/*
let mountRenderCUT;
const renderComponentUnderTest = (props) => {
if (!mountRenderCUT) {
mountRenderCUT = mount(<${1:${TM_FILENAME/(.+)\..+|.*/$1/:ComponentUnderTest}} {...props} />);
}
return mountRenderCUT;
};
*/
beforeEach(() => {
defaultProps = {
${4:propMethodToMock}: jest.fn(),
${5:propString}: 'text string',
${6:propObject: {
firstName: 'Johnny5',
plan: 'sandbox',
planPending: false,
}},
};
shallowRenderCUT = undefined;
// mountRenderCUT = undefined;
componentUnderTest = renderComponentUnderTest(defaultProps);
});
it('always renders a container `div`', () => {
const containers = componentUnderTest.find('div');
expect(containers.length).toBeGreaterThan(0);
});
describe('the rendered container', () => {
it('has the expected class', () => {
const containers = componentUnderTest.find('div');
const wrappingDiv = containers.first();
expect(wrappingDiv.hasClass('${7:someClassName}')).toBe(true);
});
it('contains everything else that gets rendered', () => {
const containers = componentUnderTest.find('div');
// When using .find, enzyme arranges the nodes in order such
// that the outermost node is first in the list. So we can
// use .first() to get the outermost div.
const wrappingDiv = containers.first();
// Enzyme omits the outermost node when using the .children()
// method on componentUnderTest. This is annoying, but we can use it
// to verify that wrappingDiv contains everything else this
// component renders.
expect(wrappingDiv.children()).toEqual(componentUnderTest.children());
});
it('always renders a `${3:ChildComponent}`', () => {
expect(componentUnderTest.find(${3:ChildComponent}).length).toBe(1);
});
});
describe('the rendered `${3:ChildComponent}`', () => {
it('receives the ${4:propMethodToMock} prop passed to ${1:${TM_FILENAME/(.+)\..+|.*/$1/:ComponentUnderTest}}', () => {
const button = componentUnderTest.find(${3:ChildComponent});
const buttonProps = button.props();
expect(Object.keys(buttonProps)).toContain('onClick');
expect(buttonProps.onClick).toBe(defaultProps.${4:propMethodToMock});
});
});
});
]]></content>
<!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
<tabTrigger>test:react-component-with-enzyme</tabTrigger>
<!-- Optional: Set a scope to limit where the snippet will trigger -->
<scope>source.js</scope>
<description>Unit Test: React Component with Enzyme</description>
</snippet>
@dgowrie

dgowrie commented Sep 19, 2018

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment