Last active
September 19, 2018 05:27
-
-
Save dgowrie/146b68ef5754d617973506bb7eace57c to your computer and use it in GitHub Desktop.
Sublime Text Snippet: Unit Test - React Component with Enzyme
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <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> |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Lots of inspiration, example code taken from:
https://medium.freecodecamp.org/the-right-way-to-test-react-components-548a4736ab22
Other resources: