{"pageProps":{"data":{"title":"A simple structure to test React components in Jest","date":"2018-01-17T06:00:00.000Z","description":"A DRY and simple way to unit test your React components.","slug":"testing-components-with-jest","locale":"en-US","dateFormatted":"Wednesday, January 17, 2018"},"content":{"compiledSource":"\"use strict\";\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsx mdx */\nvar layoutProps = {};\nvar MDXLayout = \"wrapper\";\n\nfunction MDXContent(_ref) {\n var components = _ref.components,\n props = _objectWithoutProperties(_ref, [\"components\"]);\n\n return mdx(MDXLayout, _extends({}, layoutProps, props, {\n components: components,\n mdxType: \"MDXLayout\"\n }), mdx(\"p\", null, \"Each and every time I write a test for a React component, I've found myself using the same structure over and over when testing React components.\"), mdx(\"p\", null, \"Let's consider an \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"Icon\"), \" component that accepts a prop \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"name\"), \".\"), mdx(\"pre\", {\n \"className\": \"language-jsx\"\n }, mdx(\"code\", _extends({\n parentName: \"pre\"\n }, {\n \"className\": \"language-jsx\"\n }), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"import\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token maybe-class-name\"\n }), \"React\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"from\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'react'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"export\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"default\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"function\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token maybe-class-name\"\n }), \"Icon\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token parameter\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \" name \", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"const\"), \" className \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token template-string\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token template-punctuation string\"\n }), \"`\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token string\"\n }), \"icon-\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token interpolation\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token interpolation-punctuation punctuation\"\n }), \"${\"), \"name\", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token interpolation-punctuation punctuation\"\n }), \"}\")), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token template-punctuation string\"\n }), \"`\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"return\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"<\"), \"i\"), \" \", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token attr-name\"\n }), \"className\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token script language-javascript\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token script-punctuation punctuation\"\n }), \"=\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"className\", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\")), \" \", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"/>\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), \"\\n\")), mdx(\"p\", null, \"And its corresponding test:\"), mdx(\"pre\", {\n \"className\": \"language-jsx\"\n }, mdx(\"code\", _extends({\n parentName: \"pre\"\n }, {\n \"className\": \"language-jsx\"\n }), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"import\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token maybe-class-name\"\n }), \"React\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"from\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'react'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"import\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \" shallow \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"from\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'enzyme'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\\n\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"import\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token maybe-class-name\"\n }), \"Icon\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword module\"\n }), \"from\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'./Icon'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\\n\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"describe\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'Icon'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token arrow operator\"\n }), \"=>\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"let\"), \" tree\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" props\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"const\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function-variable function\"\n }), \"buildTree\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token parameter\"\n }), \"newProps \", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token arrow operator\"\n }), \"=>\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"const\"), \" defaultProps \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n name\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'add'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\\n props \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token known-class-name class-name\"\n }), \"Object\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token method function property-access\"\n }), \"assign\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" defaultProps\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" newProps\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token keyword\"\n }), \"return\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"shallow\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token tag\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"<\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token class-name\"\n }), \"Icon\")), \" \", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token spread\"\n }), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"...\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token attr-value\"\n }), \"props\"), mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\")), \" \", mdx(\"span\", _extends({\n parentName: \"span\"\n }, {\n \"className\": \"token punctuation\"\n }), \"/>\")), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"it\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'matches the snapshot'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token arrow operator\"\n }), \"=>\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n tree \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"buildTree\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"expect\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), \"tree\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token method function property-access\"\n }), \"toMatchSnapshot\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"it\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'adds the proper className given an icon name'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \",\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token arrow operator\"\n }), \"=>\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \"\\n tree \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \"=\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"buildTree\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"{\"), \" name\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token operator\"\n }), \":\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'delete'\"), \" \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token function\"\n }), \"expect\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), \"tree\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token method function property-access\"\n }), \"hasClass\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token string\"\n }), \"'icon-delete'\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \".\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token method function property-access\"\n }), \"toBe\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"(\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token boolean\"\n }), \"true\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n \", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\", mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \"}\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \")\"), mdx(\"span\", _extends({\n parentName: \"code\"\n }, {\n \"className\": \"token punctuation\"\n }), \";\"), \"\\n\")), mdx(\"p\", null, \"The key here is the \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"buildTree\"), \" function. This function will be used throughout all the test cases. It helps us define the instance of the component given a minimal amount of typing.\"), mdx(\"p\", null, \"Calling \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"buildTree\"), \" without arguments will return a \\u2018default\\u2019 instance of the component. What we mean by \\u2018default\\u2019 is up to us. However, we can an new props inside an object. This object will merge with the \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"defaultProps\"), \" and return a component with the props we defined.\"), mdx(\"p\", null, \"In the Icon example, we tested the default case for an Icon component with a snapshot. In our second test case, we tested specifically to check if the resulting element did indeed have the className we expect it to have. To do that we explicitly passed a new \", mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"name\"), \".\"), mdx(\"p\", null, mdx(\"inlineCode\", {\n parentName: \"p\"\n }, \"buildTree\"), \" will prove very useful for more complex components, specially those with many props, and therefore possibly many test cases. By having a simple way to create instances of our component we can keep our code short and brief and consequently keep our test code clean.\"));\n}\n\n;\nMDXContent.isMDXComponent = true;","renderedOutput":"
Each and every time I write a test for a React component, I've found myself using the same structure over and over when testing React components.
Let's consider an Icon
component that accepts a prop name
.
import React from 'react';\nexport default function Icon({ name }) {\n const className = `icon-${name}`;\n return <i className={className} />;\n}\n
And its corresponding test:
import React from 'react';\nimport { shallow } from 'enzyme';\n\nimport Icon from './Icon';\n\ndescribe('Icon', () => {\n let tree, props;\n\n const buildTree = (newProps = {}) => {\n const defaultProps = {\n name: 'add',\n };\n\n props = Object.assign({}, defaultProps, newProps);\n\n return shallow(<Icon {...props} />);\n };\n\n it('matches the snapshot', () => {\n tree = buildTree();\n expect(tree).toMatchSnapshot();\n });\n\n it('adds the proper className given an icon name', () => {\n tree = buildTree({ name: 'delete' });\n\n expect(tree.hasClass('icon-delete')).toBe(true);\n });\n});\n
The key here is the buildTree
function. This function will be used throughout all the test cases. It helps us define the instance of the component given a minimal amount of typing.
Calling buildTree
without arguments will return a ‘default’ instance of the component. What we mean by ‘default’ is up to us. However, we can an new props inside an object. This object will merge with the defaultProps
and return a component with the props we defined.
In the Icon example, we tested the default case for an Icon component with a snapshot. In our second test case, we tested specifically to check if the resulting element did indeed have the className we expect it to have. To do that we explicitly passed a new name
.
buildTree
will prove very useful for more complex components, specially those with many props, and therefore possibly many test cases. By having a simple way to create instances of our component we can keep our code short and brief and consequently keep our test code clean.