{"id":124,"date":"2018-09-03T14:23:05","date_gmt":"2018-09-03T14:23:05","guid":{"rendered":"https:\/\/159.69.80.24\/blog\/what-and-how-to-test-with-enzyme-and-jest-full-instruction-on-react-component-testing\/"},"modified":"2025-10-21T09:25:20","modified_gmt":"2025-10-21T09:25:20","slug":"jest-enzyme-react-unit-testing","status":"publish","type":"post","link":"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/","title":{"rendered":"Unit Testing in React: Full Guide on Jest and Enzyme Testing"},"content":{"rendered":"<p>Unit testing React components with Jest may be challenging for beginners and <a href=\"https:\/\/djangostars.com\/services\/react-native-development\/\">experienced developers<\/a> who have already worked with tests. It may be interesting to compare your approaches with the ones we use in our project. To cover the codebase, you have to know which React components must be tested and which code exactly in the component should be covered.<\/p>\n<p>In this article, I\u2019ll cover the next topics:<\/p>\n<ul>\n<li>the correct order of components\u2019 testing based on project structure;<\/li>\n<li>what to omit in test coverage (what not to test);<\/li>\n<li>the necessity of Snapshot Testing;<\/li>\n<li>what to test in the component and in which order;<\/li>\n<li>detailed custom code examples.<\/li>\n<\/ul>\n<p>The article requires that the reader already has knowledge about Jest and Enzyme setup. You may learn about its installation and configuration on the <a href=\"https:\/\/jestjs.io\/docs\/tutorial-react\">official website<\/a>. We will also share Enzyme test cases in React. <!--We will also share best practices for React unit testing. -->In addition, you can see <a href=\"https:\/\/djangostars.com\/case-studies\/\">our case studies<\/a>.<\/p>\n<p>Assume the following case: you need to cover the project codebase with tests, so what should you start with and get at the end of testing? 100% test coverage? It is the indicator to which you should aspire, but you won\u2019t get it in most situations. It&#8217;s because you shouldn\u2019t test all the code. We will find out why and what should be left out of tests. Furthermore, 100% test coverage does not always ensure the component is fully tested. Also, there is no guarantee it will notify you if something has been changed. Don\u2019t strive for the percentages, avoid writing fake tests, and just try not to lose main component details.<\/p>\n<h2>Defining the correct order of testing React components based on project structure<\/h2>\n<p>Let\u2019s discuss this question in the next part of the project structure:<br \/>\n<img decoding=\"async\" class=\"alignnone size-full wp-image-4491\" src=\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/The-Directory-Being-Tested.png\" alt=\"Project Structure Containing Components\" width=\"1440\" height=\"1256\" srcset=\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/The-Directory-Being-Tested.png 1440w, https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/The-Directory-Being-Tested-300x262.png 300w, https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/The-Directory-Being-Tested-1024x893.png 1024w, https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/The-Directory-Being-Tested-768x670.png 768w, https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/The-Directory-Being-Tested-172x150.png 172w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><br \/>\nI took the <code>shared<\/code> directory because it is the most important; it consists of the components that are used in several different pages of the project. They are reusable, and normally, they are small and not complex. If one or another component fails, it will cause failure in other places. That\u2019s why we should be confident that they have been written correctly. The structure of this directory is divided into several folders, each containing components.<br \/>\n<img decoding=\"async\" class=\"alignnone size-full wp-image-4492\" src=\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/Defining-Queue-for-Test-Coverage.png\" alt=\"Defining queue for project structure\" width=\"1440\" height=\"1256\" srcset=\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/Defining-Queue-for-Test-Coverage.png 1440w, https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/Defining-Queue-for-Test-Coverage-300x262.png 300w, https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/Defining-Queue-for-Test-Coverage-1024x893.png 1024w, https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/Defining-Queue-for-Test-Coverage-768x670.png 768w, https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/Defining-Queue-for-Test-Coverage-172x150.png 172w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><br \/>\nHow to define the correct order of React component testing in the <code>shared<\/code> directory:<\/p>\n<ul>\n<li>Always follow the rule &#8220;from simple to complex.&#8221; Analyze each directory and define which components are <code>independent<\/code> \u2014 namely, their rendering doesn\u2019t depend on the other components; they are self-completed and can be used separately as a single unit. From the structure above, it is the <code>inputs<\/code> directory in the <code>forms<\/code> folder. It contains input components to redux-forms, such as TextInput, SelectInput, CheckboxInput, DateInput, etc.<\/li>\n<li>Next, I need to define auxiliary components that are often used in the <code>inputs<\/code> components, but should be tested separately from them. This is the <code>utils<\/code> directory. Components in this folder are not complicated, but very important. They are frequently reusable and help with repeated actions.<\/li>\n<li>The next step is to define which components can be used independently too. If any, take them for testing. From our structure, it is <code>widgets<\/code>, the little components with simple functionality. They will be the third item in the queue for test coverage.<\/li>\n<li>Further, analyze the rest of the directories and define more complex components, which can be used independently or in conjunction with other components. In our case, it is <code>modals<\/code> directory; these components will be explained in detail below.<\/li>\n<li>The most complex for testing components are left in the end. They are the <code>hoc<\/code> directory and the <code>fields<\/code> from the <code>forms<\/code> folder. How do you define which one should be tested first? I take the directory from which components have already been used in tested components. Thus, the component from the <code>hoc<\/code> directory was present in the <code>widgets<\/code> component; that\u2019s why I already know where and with which purpose this directory and its component are used.<\/li>\n<li>The last one is the <code>fields<\/code> folder; it contains components connected with redux-forms.<\/li>\n<\/ul>\n<p>The final components order (based on our example) will look like this:<br \/>\n<img decoding=\"async\" class=\"alignnone size-full wp-image-4493\" src=\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/Component-Testing-Order.png\" alt=\"Final components order project structure\" width=\"1440\" height=\"1256\" srcset=\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/Component-Testing-Order.png 1440w, https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/Component-Testing-Order-300x262.png 300w, https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/Component-Testing-Order-1024x893.png 1024w, https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/Component-Testing-Order-768x670.png 768w, https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2022\/10\/Component-Testing-Order-172x150.png 172w\" sizes=\"(max-width: 1440px) 100vw, 1440px\" \/><br \/>\nFollowing this order, you increase the complexity of the tested components step by step; thus, when it comes to operating with the more complex components, you already know how the smallest ones behave. Don\u2019t take for testing, for example, the \u2018array\u2019 field, if you are not sure how to test the \u2018text\u2019 field; don\u2019t take components decorated with redux-form if you haven\u2019t tested the \u2018form\u2019 field itself. Be consistent in your choices, don\u2019t take the first component that comes into your mind, and switch on logic. Of course, the structure of your project can differ; it can have other directory names or additional components, actions, and reducers, but the logic of defining the order for testing the components is the same.<\/p>\n<p><strong>Let\u2019s define what should be omitted in test coverage:<\/strong><\/p>\n<ol>\n<li><strong><em>Third-party libraries<\/em><\/strong>. Don\u2019t test functionality that is taken from another library; you are not responsible for that code. Skip it or imitate implementation if you need it to test your code.<\/li>\n<li><strong><em>Constants<\/em><\/strong>. The name speaks for itself. They are not changeable; it is a set of static code that is not intended to vary.<\/li>\n<li><strong><em>Inline styles<\/em><\/strong> (if you use them in component). To test inline styles, you need to duplicate object with styles in your test; if styles object changes, you must change it in the test too. Don\u2019t duplicate component\u2019s code in tests; you will never keep in mind to change it in tests. Moreover, your colleague will never guess about duplication. In most cases, inline styles don\u2019t change the component\u2019s behavior; consequently, they shouldn\u2019t be tested. There can be an exception in case your styles change dynamically.<\/li>\n<li><strong><em>Things not related to the tested component<\/em><\/strong>. Skip covering with tests components that were imported in the tested component; be careful if it is wrapped in another one. Don\u2019t test wrapper, just analyze and test them separately.<\/li>\n<\/ol>\n<p>Now, let&#8217;s move on to Jest testing React application. When using Jest, React code tests can be run similarly to other JavaScript code tests. And thanks to Enzyme, React \u0441omponents&#8217; output can be manipulated in easier ways, which speeds up testing.<\/p>\n<p>So how do you actually write React component tests? I combine two testing approaches:<\/p>\n<ul>\n<li>Snapshot Testing<\/li>\n<li>Component logic testing<\/li>\n<\/ul>\n<p>Snapshot Testing is a testing tool available in Jest for React unit testing. It\u2019s useful in case you want to be sure the user interface hasn\u2019t changed. When facing this testing tool for the first time, questions arise concerning organization and managing snapshots. The principle of work is very simple, but unfortunately, it has not been fully described anywhere; on the official website jestjs.io, the description of Snapshot Testing work is very poor.<br \/>\n<div class=\"info_box_shortcode_holder\" style=\"background-image: url(https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2023\/08\/Mobile-Development.png)\">\n    <div class=\"info_box_label\">\n    Services\n    <\/div>\n    <div class=\"info_box_logo\">\n    \n    <\/div>\n    \n    <div class=\"info_box_title font_size_\">\n   <span class=\"info_box_title_inner\">Unleash app potential. Go mobile.&lt;br \/&gt;\n<\/span>\n    <\/div>\n    <div class=\"info_box_link\">\n        <a href=\"https:\/\/djangostars.com\/services\/mobile-app-development\/\" target=\"_blank\" >\n            <span>Learn more<\/span>\n            <div class=\"button_animated\">\n                <svg width=\"24\" height=\"12\" viewBox=\"0 0 24 12\" fill=\"none\"\n                     xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                    <path d=\"M23.725 5.33638C23.7248 5.3361 23.7245 5.33577 23.7242 5.33549L18.8256 0.460497C18.4586 0.0952939 17.865 0.096653 17.4997 0.463684C17.1345 0.830668 17.1359 1.42425 17.5028 1.7895L20.7918 5.06249H0.9375C0.419719 5.06249 0 5.48221 0 5.99999C0 6.51777 0.419719 6.93749 0.9375 6.93749H20.7917L17.5029 10.2105C17.1359 10.5757 17.1345 11.1693 17.4998 11.5363C17.865 11.9034 18.4587 11.9046 18.8256 11.5395L23.7242 6.66449C23.7245 6.66421 23.7248 6.66388 23.7251 6.6636C24.0923 6.29713 24.0911 5.70163 23.725 5.33638Z\"\n                          fill=\"#282828\"><\/path>\n                <\/svg>\n                <div class=\"shape\"><\/div>\n            <\/div>\n        <\/a>\n    <\/div>\n<\/div><\/p>\n<h2>How to test with snapshots<\/h2>\n<p>When using Jest and Enzyme, unit testing in React apps with snapshots can proceed in the following order. So, let\u2019s test React components with Jest and Enzyme.<\/p>\n<p><strong>Step 1.<\/strong> Write a test for the component and in the expect block, use <code>.toMatchSnapshot()<\/code> method that creates <code>Snapshot<\/code> itself.<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Create+snapshot+for+TextInput+components%29+TextInput.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>Step 2.<\/strong> When you run the test for the first time on the one level, along with the test, there will be a created directory named <code>__snapshots__<\/code> with the autogenerated file inside with the extension<code>.snap<\/code>.<\/p>\n<p>A snapshot looks like this:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Snapshot+example%29+TextInput.test.js.snap\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>Step 3.<\/strong> Push the snapshot into the repository and store it along with the test.<\/p>\n<p>If component has been changed, you need just to update the snapshot with the <code>\u2014updateSnapshot<\/code> flag or using the short form <code>u<\/code> flag.<\/p>\n<h3>Snapshot is created; how does it work?<\/h3>\n<p>Let us consider two cases:<\/p>\n<h4>1. The component has changed<\/h4>\n<ul>\n<li>Run tests.<\/li>\n<li>A new snapshot is created, and it compares with the auto-generated snapshot stored in the directory <code>__snapshots__<\/code>.<\/li>\n<li>Tests failed because snapshots are different.<\/li>\n<\/ul>\n<p><img decoding=\"async\" class=\"alignnone wp-image-316 size-full\" src=\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2018\/11\/fail.gif\" alt=\"fail-Tests-failed-Snapshot\" width=\"772\" height=\"704\" \/><\/p>\n<h4>2. The component has not changed<\/h4>\n<ul>\n<li>Run tests.<\/li>\n<li>A new snapshot is created, and it compares with the auto-generated snapshot stored in the directory <code>__snapshots__<\/code>.<\/li>\n<li>Tests passed because snapshots are identical.<\/li>\n<\/ul>\n<p><img decoding=\"async\" class=\"alignnone wp-image-319 size-full\" src=\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2018\/11\/success.gif\" alt=\"success-Tests-failed-Snapshot\" width=\"772\" height=\"704\" \/><br \/>\nEverything is fine when I test a small component without logic, just UI rendering, but as practice shows, there are no such components on real projects. If there are, they are in a small amount.<\/p>\n<h3>Is there enough snapshot for full component testing?<\/h3>\n<p>The answer is \u201cNo\u201d. I stick to the approach to combine Snapshot Testing with manually written tests for component logic. The reason is in the component\u2019s states, props, and conditions inside. One snapshot can be generated with one current state or condition of the component. What do you do with the others? Create 5-10 snapshots and store them along with the test? I would say it is not a right way, so don\u2019t practice this technique. Use snapshots for testing UI and manually written tests for testing functionality.<\/p>\n<h2>Main instructions for testing React components with Jest<\/h2>\n<p><strong>1. One component should have only one snapshot.<\/strong> If one snapshot fails, most likely the others will fail too, so do not create and store a bunch of unnecessary snapshots clogging the space and confusing developers who will read your tests after you. Of course, there are exceptions when you need to test the behavior of a component in two states; for example, in the state of the component before opening the pop-up and after opening. However, even such variant can always be replaced by this one: the first test stores default state of the component without popup in snapshot, and the second test simulates event and checks the presence of a particular class. In this way, you can easily bypass the creation of several snapshots.<\/p>\n<p><strong>2. Testing props:<\/strong> As a rule, I divide the testing of the props into two tests:<\/p>\n<p>&#8211; Firstly, check the render of default prop values; when the component is rendered, I expect a value to be equal to <code>defaultProps<\/code> in case this prop has <code>defaultProps<\/code>.<br \/>\n&#8211; Secondly, check the custom value of the prop; I set my own value and expect it to be received after the component&#8217;s render.<\/p>\n<p><strong>3. Testing data types:<\/strong> To test what type of data comes in the props or what kind of data is obtained after certain actions, I use the special library jest-extended (Additional Jest matchers), which has an extended set of matches that are absent in Jest. Unit testing React data types is much easier and more enjoyable with this library. Testing proptypes is a contradictory question. Some developers can argue against proptypes testing because it is a third-party package and shouldn\u2019t be tested, but I insist on testing components\u2019 proptypes because I don\u2019t test the package functionality itself; I just ensure the proptypes are correct. Data type is a very important programming part and shouldn\u2019t be skipped.<\/p>\n<p><strong>4. Event testing:<\/strong> After creating a snapshot and covering props with tests, you can be sure of correct component rendering, but this is not enough for full coverage in case you have events in the component. You can check events in several ways; the most widely used are:<\/p>\n<ul>\n<li>mock event =&gt; simulate it =&gt; expect event was called<\/li>\n<li>mock event =&gt; simulate event with params =&gt; expect event was called with passed params<\/li>\n<li>pass necessary props =&gt; render component =&gt; simulate event =&gt; expect a certain behavior on called event<\/li>\n<\/ul>\n<p><strong>5. Testing conditions:<\/strong> Very often, you can have conditions for the output of a particular class, rendering a certain section of the code, transferring the required props, and so on. Do not forget about this because with default values, only one branch will pass the test, while the second one will remain untested. In complex components with calculations and lots of conditions, you can miss some branches. To make sure all parts of the code are covered by tests, use test coverage tool and visually check which branches are covered and which are not.<\/p>\n<p><strong>6. States\u2019 testing:<\/strong> To check the state, in most cases, it is necessary to write two tests:<\/p>\n<ul>\n<li>The first one checks the current state.<\/li>\n<li>The second one checks the state after calling the event. Render component =&gt; call function directly in the test =&gt; check how the state has changed. To call function of the component, you need to get an instance of the component and only then call its methods (an example is shown in the <a href=\"https:\/\/github.com\/ned-alyona\/testing-jest-enzyme\/blob\/master\/shared\/modals\/__tests__\/ModalTrigger.test.js#L30\">next test<\/a>).<\/li>\n<\/ul>\n<p>After you walk through this list of instructions, your component will be covered from 90% to 100%. I leave 10% for special cases that were not described in the article but can occur in the code.<\/p>\n<h2>Examples of Jest React component testing<\/h2>\n<p>To help you figure out how to prepare unit test cases in React.js, let\u2019s move to examples and cover testing React components with Jest step by step under the above-described structure.<\/p>\n<h3>1. Testing of a component from forms\/inputs.<\/h3>\n<p>Take one component from the forms\/inputs directory; let it be DateInput.js, the component for the datepicker field.<\/p>\n<p><strong>Code listing for the tested component: <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/forms\/inputs\/DateInput.js\">DateInput.js<\/a><br \/>\nLooks like:<\/strong><br \/>\n<img decoding=\"async\" class=\"alignnone wp-image-315 size-full\" src=\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2018\/11\/Datepicker.gif\" alt=\"component-for-datepicker-field\" width=\"628\" height=\"294\" \/><br \/>\nDateInput component uses the react-datepicker library with two utilities: valueToDate (converts a value to a date) and dateToValue is vice versa, the moment package for manipulating the date and PropTypes for checking React props.<\/p>\n<p>According to the component code, we can see the list of default props with the help of which the component should be rendered:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28defaultProps+for+DateInput+component%29+DateInput.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nAll props are appropriate for creating a snapshot, except one <code>minDate: moment()<\/code>, moment() will give us the current date each time we run the test, and the snapshot will fail because it stores outdated date. The solution is to mock this value:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Mock+moment+date%29+DateInput.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nminDate prop I need in each rendered component; to avoid props duplication, I create HOC, which receives defaultProps and returns pretty component:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28HOC+for+DateInput.js+which+receives+defaultProps%29+DateInput.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nDon\u2019t forget about <code>moment-timezone<\/code>, especially if your tests will be run by developers from another country in a different time zone. They will receive mocked value but with a time zone shift. The solution is to set the default time zone:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Set+default+moment+time+zone%29+DateInput.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nNow the date input component is ready for testing:<\/p>\n<p><strong>1. Create snapshot first<\/strong><br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Create+snapshot+for+DateInput+component%29+DateInput.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>2. Testing props:<\/strong><br \/>\nLook through props and find important; first prop to test is showMonthYearsDropdowns, if it set to true, the dropdown for month and years is shown:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Test+showMonthYearsDropdowns+prop%2C+check+datepicker+month+and+years+dropdowns+displayed%29+DateInput.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nTest null prop value; this check is required to ensure the component is rendered without a defined value:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Test+datepicker+with+null+value%29+DateInput.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>3. Test proptypes for value, date expected to be a string:<\/strong><br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Test+proptypes+for+value%2C+date+expected+to+be+string%29+DateInput.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>4. Test events:<\/strong><\/p>\n<ul>\n<li>Check the onChange event for that mock onChange callback =&gt; render date input component =&gt; then simulate change event with new target value =&gt; and finally check that onChange event have been called with new value.<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Test+onChange+event%29+DateInput.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><\/li>\n<li>Ensure the datepicker popup opens after clicking on the date input. For that, find the date input =&gt; simulate click event =&gt; and expect the popup with a <code>.react-datepicker<\/code> class is present.<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Check+datepicker+popup+open%29+DateInput.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>Full tests listing:<\/strong> <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/forms\/inputs\/__tests__\/DateInput.test.js\">DateInput.test.js<\/a><\/li>\n<\/ul>\n<h3>2. Utility testing:<\/h3>\n<p><strong>Code listing for tested utility:<\/strong> <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/utils\/valueToDate.js\">valueToDate.js<\/a><br \/>\nThe purpose of this utility is to transform value to date with custom format.<\/p>\n<p>First of all, let\u2019s analyze the given utility and define the main cases for testing:<\/p>\n<p><strong>1.<\/strong> According to the purpose of this utility, it transforms value, so we need to check this value:<\/p>\n<ul>\n<li>If the value is not defined, we need to be sure that the utility will not return an exception (error).<\/li>\n<li>In case the value is defined, we need to check that the utility returns the moment date.<\/li>\n<\/ul>\n<p><strong>2.<\/strong> The returned value should belong to the moment class; that\u2019s why it should be an instance of moment.<\/p>\n<p><strong>3.<\/strong> The second argument is dateFormat; set it as constant before tests. That\u2019s why it will be passed in each test and return a value according to the date format. Should we test dateFormat separately? I suppose no. This argument is optional; if we don\u2019t set dateFormat, the utility won\u2019t break, and it\u2019ll just return the date in default format. It is a moment job, we shouldn\u2019t test third-party libraries.<\/p>\n<p>As I mentioned before, we shouldn\u2019t forget about moment-timezone; it is a very important point, especially for developers from different time zones.<\/p>\n<p><strong>Let\u2019s code:<\/strong><\/p>\n<p><strong>1. Write a test for the first case; when we don\u2019t have value, it is empty.<\/strong><br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Check+valueToDate+utility+with+empty+value%29+valueToDate.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>2. Check if the value is defined.<\/strong><br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Check+if+value+is+defined%29+valueToDate.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>3. Check if the value belongs to the moment class.<\/strong><br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Check+if+the+value+belongs+to+the+moment+class%29+valueToDate.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>Full tests listing:<\/strong> <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/utils\/__tests__\/valueToDate.test.js\">valueToDate.test.js<\/a><\/p>\n<h3>3. Widgets testing<\/h3>\n<p>For widgets testing, I took spinner component.<\/p>\n<p><strong>Code listing for tested widget:<\/strong> <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/widgets\/Spinner.js\">Spinner.js<\/a><br \/>\n<strong><em>Looks like:<\/em><\/strong><br \/>\n<img decoding=\"async\" class=\"alignnone wp-image-318 size-full\" src=\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2018\/11\/spinner.gif\" alt=\"spinner-code\" width=\"1092\" height=\"374\" \/><br \/>\nSpinner is not required in explanation, as almost all web resources have this component.<\/p>\n<p>So go to write tests:<\/p>\n<p><strong>1. First step &#8211; create a snapshot:<\/strong><br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Create+snapshot+for+spinner+widget%29+Spinner.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>2. Testing props:<\/strong><\/p>\n<p><strong>2.1<\/strong> Default prop title, check if it renders correctly.<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Check+default+prop+title%29+Spinner.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>2.2<\/strong> Check custom prop title; I need to check that it returns correctly defined prop. Take a look at the code, the title wrapped in the rawMarkup util, and outputs with the help of the dangerouslySetInnerHTML property.<\/p>\n<p>Code listing for rawMarkup util:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Code+listing+for+rawMarkup+util%29+rawMarkup.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nDo we need to include tests for rawMarkup in the spinner component? No, it is a separate utility and it should be tested separately from the spinner. We don\u2019t care how it works; we just need to know that title prop returns the correct result.<\/p>\n<p>Clarification: The reason for using dangerouslySetInnerHTML property is as follows. Our site is multilingual, and the marketing team is responsible for its translations. They can translate it simply with a combination of words or even decorate with HTML tags, like <code>&lt;strong&gt;<\/code>, <code>&lt;i&gt;<\/code>, <code>&lt;s&gt;<\/code> or even slice text with the lists <code>&lt;ol&gt;<\/code>, <code>&lt;ul&gt;<\/code>; we don\u2019t know for sure how they translate and decorate the text. We just need to correctly render all this stuff.<\/p>\n<p>I combined two main test cases in one test:<\/p>\n<ul>\n<li>return the correct custom prop title<\/li>\n<li>render correctly prop title with HTML tags<\/li>\n<\/ul>\n<p><div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Render+prop+title+correctly+with+HTML+tags%29+Spinner.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nTake the next prop subTitle; it is optional, and that\u2019s why it doesn\u2019t have default prop, so skip the step with default props and test custom props:<\/p>\n<ul>\n<li>Check that the text in the subTitle prop renders correctly:<\/li>\n<\/ul>\n<p><div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Check+text+in+subTitle+prop+renders+correctly%29+Spinner.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nWe know that subTitle is optional; that\u2019s why we need to check whether it is not rendered with default props, according to the slicing markup. Just check the number of tags <code>&lt;p&gt;<\/code>:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Check+subTitle+is+not+rendered%29+Spinner.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>3. Testing prop types:<\/strong><\/p>\n<ul>\n<li>For title prop expected to be a string:<\/li>\n<\/ul>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Testing+prop+type+for+title+prop%29+Spinner.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div>\n<ul>\n<li>For subTitle prop also expected to be a string:<\/li>\n<\/ul>\n<p><div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Testing+prop+type+for+subTitle+prop%29+Spinner.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>Full tests listing:<\/strong> <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/widgets\/__tests__\/Spinner.test.js\">Spinner.test.js<\/a><\/p>\n<h3>4. Modals testing (ModalWrapper.js and ModalTrigger.js)<\/h3>\n<p><strong><em>Looks like:<\/em><\/strong><br \/>\n<img decoding=\"async\" class=\"alignnone wp-image-317 size-full\" src=\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2018\/11\/modal.gif\" alt=\"Modals-testing\" width=\"1066\" height=\"446\" \/><br \/>\nHow to test modals:<\/p>\n<p>First of all, I want to explain how modals are organized in our project. We have two components: <strong>ModalWrapper.js<\/strong> and <strong>ModalTrigger.js<\/strong>.<\/p>\n<p><strong>ModalWrapper<\/strong> is responsible for popup layout. It contains modal container, button \u2018close\u2019, modal title and body.<\/p>\n<p><strong>ModalTrigger<\/strong> is responsible for modal handling. It includes ModalWrapper layout and contains events for modal\u2019s layout control (open, close actions).<\/p>\n<p>I overview each component separately:<\/p>\n<p><strong>1. Code listing for tested component:<\/strong> <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/modals\/ModalWrapper.js\">ModalWrapper.js<\/a><\/p>\n<p><strong>Let\u2019s code:<\/strong><\/p>\n<p><strong>1.1<\/strong> ModalWrapper receives component and renders it inside. First of all, check that ModalWrapper won\u2019t fail without component. Create a snapshot with default props:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Create+a+snapshot+of+ModalWrapper.js+with+default+props+%28without+component%29%29+ModalWrapper.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>1.2<\/strong> The next step is to simulate its actual condition with component rendering passed through props:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Create+a+snapshot+of+ModalWrapper.js+with+component%29+ModalWrapper.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>1.3<\/strong> Testing props:<br \/>\nReceiving custom class name prop:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Receiving+custom+class+name+prop%29+ModalWrapper.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nReceiving custom title prop:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Receiving+custom+title+prop%29+ModalWrapper.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nReceiving correct show prop:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Receiving+correct+show+prop%29+ModalWrapper.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>1.4<\/strong> Testing proptypes:<\/p>\n<ul>\n<li>for show prop<\/li>\n<\/ul>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Testing+proptypes+for+show+prop%29+ModalWrapper.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div>\n<ul>\n<li>for onHide prop<\/li>\n<\/ul>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Testing+proptypes+for+onHide+prop%29+ModalWrapper.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div>\n<ul>\n<li>for component prop<\/li>\n<\/ul>\n<p><div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Testing+proptypes+for+component+prop%29+ModalWrapper.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>Full tests listing:<\/strong> <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/modals\/__tests__\/ModalWrapper.test.js\">ModalWrapper.test.js<\/a><\/p>\n<p><strong>2.Code listing for the tested component:<\/strong> <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/modals\/ModalTrigger.js\">ModalTrigger.js<\/a><\/p>\n<p>The modal wrapper has been covered with a test; the second part is to cover the modal trigger component.<\/p>\n<p>Component overview: it is based on the state <code>toggled<\/code> that indicates the visibility of ModalWrapper. If <code>toggled: false<\/code>, the popup is hidden, if else, it&#8217;s visible. Function <strong>open()<\/strong> opens popup on child element; click event and <strong>close()<\/strong> function hides popup on button rendered in ModalWrapper.<\/p>\n<p><strong>2.1<\/strong> Snapshot creation:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Create+snapshot+for+ModalTrigger+component%29+ModalTrigger.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nShould we test ModalTrigger with component prop rendering? No; because <code>component<\/code> will be rendered inside the ModalWrapper component, it does not depend on the tested component. The ModalWrapper tests already covered this.<\/p>\n<p><strong>2.2<\/strong> Testing props. We have one prop <code>children<\/code> and we want to be sure that we have only one child.<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Ensure+to+have+only+one+child+%28control+element%29%29+ModalTrigger.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>2.3<\/strong> Testing proptypes. Children prop should be object, check this in the next test:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Testing+proptypes+for+children+prop%29+ModalTrigger.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>2.4<\/strong> An important part of the ModalTrigger component is to check states.<\/p>\n<p>We have two states:<\/p>\n<p>The popup is opened. To know that the modal is opened, we need to check its state. For this, call the open function from the instance of the component and expect that <code>toggled<\/code> in state is true.<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Check+the+modal+is+opened%29+ModalTrigger.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nThe popup is closed, is tested vice versa, <code>toggled<\/code> in state should be false.<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Check+the+modal+is+closed%29+ModalTrigger.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>Full tests listing:<\/strong> <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/modals\/__tests__\/ModalTrigger.test.js\">ModalTrigger.test.js<\/a><\/p>\n<p>Now modals are fully tested. One piece of advice for testing the components that are dependent on each other: look through the components first and write test plan, define what you need to test in each component, check test cases for each component, and be sure you don\u2019t repeat the same test case in both components. Carefully analyze possible and optimal variants for test coverage.<\/p>\n<h3>5. HOC testing (Higher-Order Component)<\/h3>\n<p>The last two parts (HOC and form\u2019s fields testing) are interconnected. I would like to share with you how to test field layout with its HOC.<\/p>\n<p>Explanation of what is the BaseFieldLayout, why we need this component, and where we use it:<\/p>\n<ul>\n<li>BaseFieldLayout.js is the wrapper for form input components like TextInput, CheckboxInput, DateInput, SelectInput, etc. Their names end with the <code>-Input<\/code> because we use the redux-form package and these components are the input components to redux-form logic.<\/li>\n<li>We need BaseFieldLayout for creating layout for form field components, that is rendering label, tooltips, prefixes (currency, square meter abbreviations, etc.), icons, errors \u2026<\/li>\n<li>We use it in BaseFieldHOC.js for wrapping inputComponent in field layout and connect it with the redux-form with the help of <code>&lt;Field\/&gt;<\/code> component.<\/li>\n<\/ul>\n<p><strong>Code listing for tested component:<\/strong> <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/hoc\/BaseFieldHOC.js\">BaseFieldHOC.js<\/a><\/p>\n<p>It is a HOC, which receives a form input component and returns a component, connected with redux-form.<\/p>\n<p>Analyze HOC:<\/p>\n<ul>\n<li>This component receives only one prop, <code>component<\/code>. First of all, I need to create this component and wrap it in the BaseFieldHOC.<\/li>\n<li>Next, I need to decorate wrapped HOC with redux-form in order to get field connected with redux-form.<\/li>\n<li>Render this field inside React Redux <code>&lt;Provider&gt;<\/code> component to make the store available to the tested component.<br \/>\nTo mock store, just do:<\/li>\n<\/ul>\n<p><div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28createStore+preparation%29+ModalTrigger.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nNow, before each test, I need to do the next:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=BaseFieldHOC.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nAfter that, the component is ready for testing:<\/p>\n<p>1. Create a snapshot:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Create+snapshot+for+BaseFieldHOC%29+BaseFieldHOC.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n2. Ensure that the input component is wrapped in BaseFieldLayout after rendering:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Check+input+component+is+wrapped+in+BaseFieldLayout%29+BaseFieldHOC.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nThat\u2019s all. The HOC is covered. The most complicated part of testing connected with redux-form components is to make preparation of the field (decorate with redux form and setup store). The rest is easy; just follow the instructions and nothing else.<\/p>\n<p><strong>Full tests listing:<\/strong> <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/hoc\/__tests__\/BaseFieldHOC.test.js\">BaseFieldHOC.test.js<\/a><\/p>\n<h3>6. Forms\/fields testing<\/h3>\n<p>Field HOC has been covered with tests, and we can now move to the BaseFieldLayout component.<\/p>\n<p><strong>Code listing for the tested component:<\/strong> <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/forms\/fields\/BaseFieldLayout.js\">BaseFieldLayout.js<\/a><\/p>\n<p>Let\u2019s code BaseFieldLayout.js; write tests according to the instructions above:<\/p>\n<p><strong>1. First of all, create a snapshot.<\/strong><\/p>\n<p>This component will not be rendered without defaultProps:<\/p>\n<ul>\n<li>inputComponent<\/li>\n<li>The props provided by redux-form: input and meta objects. Input with the property name and meta with properties error and touched:<\/li>\n<\/ul>\n<p><div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28defaultProps+preparation+for+testing+BaseFieldLayout%29+BaseFieldLayout.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nTo use defaultProps in each tested wrapper, do the following:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Create+HOC+to+pass+defaultProps%29+BaseFieldLayout.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\nNow, we are ready to create a snapshot:<br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Create+snapshot+for+BaseFieldLayout+component%29+BaseFieldLayout.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>2. Testing props:<\/strong><\/p>\n<p>This component has many props. I will show examples of several ones; the rest are tested by analogy.<\/p>\n<ul>\n<li>Ensure the <code>icon<\/code> prop is rendered correctly<\/li>\n<\/ul>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Ensure+that+the+icon+prop+is+rendered+correctly%29+BaseFieldLayout.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div>\n<ul>\n<li>Ensure tooltip content renders next to the label<\/li>\n<\/ul>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Ensure+that+tooltip+content+renders+next+to+the+label%29+BaseFieldLayout.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div>\n<ul>\n<li>Testing <code>fieldLink<\/code> prop\n<ul>\n<li>Ensure fieldLink is null by default<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Ensure+that+fieldLink+is+null+by+default%29+BaseFieldLayout.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Ensure fieldLink renders correctly with custom value<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><strong>3. Testing errors:<\/strong><br \/>\n<div class=\"oembed-gist\"><script src=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1.js?file=%28Testing+errors%29+BaseFieldLayout.test.js\"><\/script><noscript>View the code on <a href=\"https:\/\/gist.github.com\/ned-alyona\/a68a910c7fef1df521b06a5d394424e1\">Gist<\/a>.<\/noscript><\/div><br \/>\n<strong>Full tests listing:<\/strong> <a href=\"https:\/\/github.com\/django-stars\/testing-jest-enzyme\/blob\/master\/shared\/forms\/fields\/__tests__\/BaseFieldLayout.test.js\">BaseFieldLayout.test.js<\/a><\/p>\n<h2>Bottom Line<\/h2>\n<p>Now you have full guidance on how to perform full coverage testing of components based on project structure. From my experience testing React components with Jest, I explained what is necessary to test, in which order, and what you can omit in test coverage. Also, I demonstrated examples of several testing components and spotted the sequence of codebase coverage. For more expertise on testing, in particular, <a href=\"https:\/\/djangostars.com\/blog\/unit-integration-testing-redux-react-forms\/\">testing of React forms<\/a>, check our blog. I hope you will find this article useful and share your response. Thank you for reading. <strong>You are welcome to contact Django Stars through the form below for consulting and dedicated team extension.<\/strong><\/p>\n<div class=\"github-widget\" data-repo=\"django-stars\/testing-jest-enzyme\"><\/div>\n<p><div class=\"lead-form-wrapper lets_disqus\">\n    <div class=\"lead-form transparent-footer\">\n        <p class=\"discuss-title paragraph-discuss col-md-12\">Have an idea? Let&#039;s discuss!<\/p>\n\n        \n<div class=\"wpcf7 no-js\" id=\"wpcf7-f2589-o1\" lang=\"en-US\" dir=\"ltr\" data-wpcf7-id=\"2589\">\n<div class=\"screen-reader-response\"><p role=\"status\" aria-live=\"polite\" aria-atomic=\"true\"><\/p> <ul><\/ul><\/div>\n<form action=\"\/blog\/wp-json\/wp\/v2\/posts\/124#wpcf7-f2589-o1\" method=\"post\" class=\"wpcf7-form init\" aria-label=\"Contact form\" enctype=\"multipart\/form-data\" novalidate=\"novalidate\" data-status=\"init\">\n<div style=\"display: none;\">\n<input type=\"hidden\" name=\"_wpcf7\" value=\"2589\" \/>\n<input type=\"hidden\" name=\"_wpcf7_version\" value=\"6.0.6\" \/>\n<input type=\"hidden\" name=\"_wpcf7_locale\" value=\"en_US\" \/>\n<input type=\"hidden\" name=\"_wpcf7_unit_tag\" value=\"wpcf7-f2589-o1\" \/>\n<input type=\"hidden\" name=\"_wpcf7_container_post\" value=\"0\" \/>\n<input type=\"hidden\" name=\"_wpcf7_posted_data_hash\" value=\"\" \/>\n<input type=\"hidden\" name=\"form_start_time\" value=\"1777077245\" \/>\n<input type=\"hidden\" name=\"_wpcf7_recaptcha_response\" value=\"\" \/>\n<\/div>\n<div class=\"form_holder\">\n    <div class=\"input_section input_row\">\n        <div class=\"input_holder\">\n                            <span class=\"input_label\">\n                               Your name *\n                            <\/span>\n            <input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" id=\"your-name\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"text-898\" \/>\n\n            <input class=\"wpcf7-form-control wpcf7-hidden\" id=\"uniq_ga_id\" value=\"\" type=\"hidden\" name=\"uniq_ga_id\" \/>\n        <\/div>\n        <div class=\"input_holder\">\n                            <span class=\"input_label\">\n                                Your email *\n                            <\/span>\n            <input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-email wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-email\" id=\"your-email\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"email\" name=\"email-882\" \/>\n        <\/div>\n    <\/div>\n    <div class=\"input_section single_input_row\">\n        <div class=\"input_holder\">\n            <span class=\"input_label\">How can we help you? *<\/span>\n            <input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text\" id=\"message\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"message\" \/>\n        <\/div>\n    <\/div>\n    <div class=\"file_attach\">\n        <input size=\"40\" class=\"wpcf7-form-control wpcf7-file\" accept=\"audio\/*,video\/*,image\/*\" aria-invalid=\"false\" type=\"file\" name=\"file-930\" \/>\n        <div class=\"file_placeholder\">\ud83d\udcce <span>Attach File<\/span>\n            <span class=\"file_formats\">Formats: pdf, doc, docx, rtf, ppt, pptx.<\/span><\/div>\n    <\/div>\n    <div class=\"checkbox_row\">\n        <div class=\"single_checkbox\"><div class=\"checkbox_indicator\"><div class=\"checked_indicator\"><svg width=\"14\" height=\"12\" viewBox=\"0 0 14 12\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M4.66804 12L0 7.26951L1.22426 6.05269L4.54927 9.40456L12.6737 0L14 1.10613L4.66804 12Z\" fill=\"#1E232C\"\/><\/svg><\/div><\/div><input type=\"checkbox\" name=\"agree\" id=\"privacy\" value=\"agree privacy\"><label for=\"privacy\" class=\"\">I have read and accepted <a href=\"https:\/\/djangostars.com\/privacy-policy\/\" style=\"margin-left: 6px;\"> Privacy Policy*<\/a><\/label><\/div>\n        <div class=\"single_checkbox\"><div class=\"checkbox_indicator\"><div class=\"checked_indicator\"><svg width=\"14\" height=\"12\" viewBox=\"0 0 14 12\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M4.66804 12L0 7.26951L1.22426 6.05269L4.54927 9.40456L12.6737 0L14 1.10613L4.66804 12Z\" fill=\"#1E232C\"\/><\/svg><\/div><\/div><input type=\"checkbox\" name=\"agree\" id=\"marketing\" value=\"agree for marketing\"><label for=\"marketing\" class=\"\">I agree to receive marketing content from Django Stars<\/label><\/div>\n    <\/div>\n    <div class=\"submit\"><button type=\"submit\"><span>send message<\/span><\/button><div class=\"safeguard\">We safeguard your privacy<\/div><\/div>\n<\/div>\n<div style=\"position: absolute; left: -5000px;\" aria-hidden=\"true\">\n    <input size=\"40\" maxlength=\"400\" class=\"wpcf7-form-control wpcf7-text\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"website_url\" \/>\n<\/div><script type='text\/javascript'>\n\n\t\t\t\t\t\tif(contactform === undefined){\n\t\t\t\t\t\t\tvar contactform = [];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvar innerVal = [2589,'mail_sent_ok','Thank you for your message. It has been sent.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'mail_sent_ng','There was an error trying to send your message. Please try again later.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'validation_error','One or more fields have an error. Please check and try again.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'spam','There was an error trying to send your message. Please try again later.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'accept_terms','You must accept the terms and conditions before sending your message.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'invalid_required','The field is required.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'invalid_too_long','The field is too long.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'invalid_too_short','The field is too short.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'upload_failed','There was an unknown error uploading the file.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'upload_file_type_invalid','You are not allowed to upload files of this type.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'upload_file_too_large','The file is too big.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'upload_failed_php_error','There was an error uploading the file.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'invalid_date','The date format is incorrect.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'date_too_early','The date is before the earliest one allowed.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'date_too_late','The date is after the latest one allowed.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'invalid_number','The number format is invalid.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'number_too_small','The number is smaller than the minimum allowed.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'number_too_large','The number is larger than the maximum allowed.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'quiz_answer_not_correct','The answer to the quiz is incorrect.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'invalid_email','The e-mail address entered is invalid.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'invalid_url','The URL is invalid.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'invalid_tel','The telephone number is invalid.'];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\tvar innerVal = [2589,'gdpr',''];\n\t\t\t\t\t\tcontactform.push(innerVal);\n\t\t\t\t\t\t<\/script><div class=\"wpcf7-response-output\" aria-hidden=\"true\"><\/div>\n<\/form>\n<\/div>\n    <\/div>\n\n    <div class=\"success_disqus\">\n        Thank you for your message.\n        <span>We\u2019ll contact you shortly<\/span>.\n    <\/div>\n<\/div>\n\n<script>\n    \/\/ (function ($) {\n    function click_input() {\n        jQuery('.file_placeholder').on('click', function () {\n            jQuery(this).parent().find('input').click();\n        })\n    }\n\n    document.addEventListener(\"DOMContentLoaded\", click_input);\n\n    \/\/ })(jQuery)\n<\/script>\n\n\n<div class=\"dj-main-article-faq\" style=\"padding-top: 0px;\">\n\t\t<div class=\"dj-main-article-faq-title\">\n\t\tFrequently Asked Questions\n\t\t<\/div>\n\t\t<div class=\"dj-main-article-faq-items\">\n\t\t\t<div class=\"dj-main-article-faq-accordeon accordeon\"><dl>\n\t\t\t\t<dt>How to test nested components in React with Jest? \n\t\t\t\t<div class=\"cross\">\n\t\t\t\t<span><\/span>\n\t\t\t\t<span><\/span>\n\t\t\t\t<\/div>\n\t\t\t\t<\/dt>\n\t\t\t\t<dd>First, define the correct order of components\u2019 testing based on project structure analysis (follow the rule from simple to complex). Define also what should be omitted in test coverage (third-party libraries, constants, inline styles, and things not related to the tested component). Then, test React components with Jest and Enzyme. It makes sense to combine Snapshot Testing with manually written tests for component logic.<\/dd>\n\t\t\t<\/dl><dl>\n\t\t\t\t<dt>What is the difference between Enzyme and Jest? \n\t\t\t\t<div class=\"cross\">\n\t\t\t\t<span><\/span>\n\t\t\t\t<span><\/span>\n\t\t\t\t<\/div>\n\t\t\t\t<\/dt>\n\t\t\t\t<dd>Jest is a Facebook-created JavaScript test runner that lets you access the DOM via jsdom, while Enzyme is an Airbnb-developed JavaScript testing utility that makes it easier to test React applications.<\/dd>\n\t\t\t<\/dl><dl>\n\t\t\t\t<dt>Can we use Jest and Enzyme together? \n\t\t\t\t<div class=\"cross\">\n\t\t\t\t<span><\/span>\n\t\t\t\t<span><\/span>\n\t\t\t\t<\/div>\n\t\t\t\t<\/dt>\n\t\t\t\t<dd>Jest, a JavaScript testing framework, pairs well with a testing utility Enzyme making it easier to test React applications. When using Jest, React code tests can be run similarly to other JavaScript code tests. Thanks to Enzyme, React components\u2019 output can be manipulated in easier ways, which speeds up testing.<\/dd>\n\t\t\t<\/dl><dl>\n\t\t\t\t<dt>How to get started writing Jest tests for React? \n\t\t\t\t<div class=\"cross\">\n\t\t\t\t<span><\/span>\n\t\t\t\t<span><\/span>\n\t\t\t\t<\/div>\n\t\t\t\t<\/dt>\n\t\t\t\t<dd>Check out our main instructions for component testing. Note that one component should have only one snapshot. (Most likely, if one snapshot fails, the others will fail too.) Check the render of default and custom prop values. Don't skip testing data types. Perform event testing. Check testing conditions. And don't forget to write tests for states' testing (check current state and state after event calling).<\/dd>\n\t\t\t<\/dl><\/div>\n\t\t\t<\/div>\n\t\t<\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Unit testing React components with Jest may be challenging for beginners and experienced developers who have already worked with tests. It may be interesting to compare your approaches with the ones we use in our project. To cover the codebase, you have to know which React components must be tested and which code exactly in [&hellip;]<\/p>\n","protected":false},"author":15,"featured_media":3553,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[44,70],"tags":[51,24],"class_list":["post-124","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python-django","category-qa","tag-frontend","tag-quality-assurance"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Software Development Blog &amp; IT Tech Insights | Django Stars<\/title>\n<meta name=\"description\" content=\"Master unit testing in React with our comprehensive guide on Jest enzyme testing. Learn best practices and tips for effective Jest and Enzyme tests.\" \/>\n<link rel=\"canonical\" href=\"https:\/\/djangostars.com\/blog\/wp-json\/wp\/v2\/posts\/124\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"React Unit Testing with Jest and Enzyme | Django Stars\" \/>\n<meta property=\"og:description\" content=\"Master unit testing in React with our comprehensive guide on Jest enzyme testing. Learn best practices and tips for effective Jest and Enzyme tests.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/\" \/>\n<meta property=\"og:site_name\" content=\"Software Development Blog &amp; IT Tech Insights | Django Stars\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/djangostars\/\" \/>\n<meta property=\"article:published_time\" content=\"2018-09-03T14:23:05+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-10-21T09:25:20+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2021\/12\/What-and-How-to-Test-with-Jest-and-Enzyme.-Full-instruction-on-React-Components-Testing.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1440\" \/>\n\t<meta property=\"og:image:height\" content=\"620\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Alyona Pysarenko\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@djangostars\" \/>\n<meta name=\"twitter:site\" content=\"@djangostars\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alyona Pysarenko\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"21 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/\"},\"author\":{\"name\":\"Alyona Pysarenko\",\"@id\":\"https:\/\/djangostars.com\/blog\/#\/schema\/person\/9c46d946e51c5e426ba3a13c642cc0d5\"},\"headline\":\"Unit Testing in React: Full Guide on Jest and Enzyme Testing\",\"datePublished\":\"2018-09-03T14:23:05+00:00\",\"dateModified\":\"2025-10-21T09:25:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/\"},\"wordCount\":5082,\"image\":{\"@id\":\"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2021\/12\/What-and-How-to-Test-with-Jest-and-Enzyme.-Full-instruction-on-React-Components-Testing.jpg\",\"keywords\":[\"Frontend\",\"Testing\"],\"articleSection\":[\"Python &amp; Django\",\"QA\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/\",\"url\":\"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/\",\"name\":\"React Unit Testing with Jest and Enzyme | Django Stars\",\"isPartOf\":{\"@id\":\"https:\/\/djangostars.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2021\/12\/What-and-How-to-Test-with-Jest-and-Enzyme.-Full-instruction-on-React-Components-Testing.jpg\",\"datePublished\":\"2018-09-03T14:23:05+00:00\",\"dateModified\":\"2025-10-21T09:25:20+00:00\",\"author\":{\"@id\":\"https:\/\/djangostars.com\/blog\/#\/schema\/person\/9c46d946e51c5e426ba3a13c642cc0d5\"},\"description\":\"Master unit testing in React with our comprehensive guide on Jest enzyme testing. Learn best practices and tips for effective Jest and Enzyme tests.\",\"breadcrumb\":{\"@id\":\"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#primaryimage\",\"url\":\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2021\/12\/What-and-How-to-Test-with-Jest-and-Enzyme.-Full-instruction-on-React-Components-Testing.jpg\",\"contentUrl\":\"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2021\/12\/What-and-How-to-Test-with-Jest-and-Enzyme.-Full-instruction-on-React-Components-Testing.jpg\",\"width\":1440,\"height\":620,\"caption\":\"What-and-How-to-Test-with-Jest-and-Enzyme\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/djangostars.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Unit Testing in React: Full Guide on Jest and Enzyme Testing\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/djangostars.com\/blog\/#website\",\"url\":\"https:\/\/djangostars.com\/blog\/\",\"name\":\"Software Development Blog &amp; IT Tech Insights | Django Stars\",\"description\":\"Welcome behind the scenes of software product development. We share our best practices, tech solutions, management tips, and every useful insight we\u2018ve got while working on our projects.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/djangostars.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/djangostars.com\/blog\/#\/schema\/person\/9c46d946e51c5e426ba3a13c642cc0d5\",\"name\":\"Alyona Pysarenko\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/djangostars.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a15268f619d10a27871d8fa2db4cb2a8cc2e444e78aa3a899a1e539e5474a5ba?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a15268f619d10a27871d8fa2db4cb2a8cc2e444e78aa3a899a1e539e5474a5ba?s=96&d=mm&r=g\",\"caption\":\"Alyona Pysarenko\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/nedelchenko-alyona-2663bb78\/\"],\"url\":\"https:\/\/djangostars.com\/blog\/author\/alona-pysarenko\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Software Development Blog &amp; IT Tech Insights | Django Stars","description":"Master unit testing in React with our comprehensive guide on Jest enzyme testing. Learn best practices and tips for effective Jest and Enzyme tests.","canonical":"https:\/\/djangostars.com\/blog\/wp-json\/wp\/v2\/posts\/124","og_locale":"en_US","og_type":"article","og_title":"React Unit Testing with Jest and Enzyme | Django Stars","og_description":"Master unit testing in React with our comprehensive guide on Jest enzyme testing. Learn best practices and tips for effective Jest and Enzyme tests.","og_url":"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/","og_site_name":"Software Development Blog &amp; IT Tech Insights | Django Stars","article_publisher":"https:\/\/www.facebook.com\/djangostars\/","article_published_time":"2018-09-03T14:23:05+00:00","article_modified_time":"2025-10-21T09:25:20+00:00","og_image":[{"width":1440,"height":620,"url":"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2021\/12\/What-and-How-to-Test-with-Jest-and-Enzyme.-Full-instruction-on-React-Components-Testing.jpg","type":"image\/jpeg"}],"author":"Alyona Pysarenko","twitter_card":"summary_large_image","twitter_creator":"@djangostars","twitter_site":"@djangostars","twitter_misc":{"Written by":"Alyona Pysarenko","Est. reading time":"21 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#article","isPartOf":{"@id":"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/"},"author":{"name":"Alyona Pysarenko","@id":"https:\/\/djangostars.com\/blog\/#\/schema\/person\/9c46d946e51c5e426ba3a13c642cc0d5"},"headline":"Unit Testing in React: Full Guide on Jest and Enzyme Testing","datePublished":"2018-09-03T14:23:05+00:00","dateModified":"2025-10-21T09:25:20+00:00","mainEntityOfPage":{"@id":"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/"},"wordCount":5082,"image":{"@id":"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#primaryimage"},"thumbnailUrl":"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2021\/12\/What-and-How-to-Test-with-Jest-and-Enzyme.-Full-instruction-on-React-Components-Testing.jpg","keywords":["Frontend","Testing"],"articleSection":["Python &amp; Django","QA"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/","url":"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/","name":"React Unit Testing with Jest and Enzyme | Django Stars","isPartOf":{"@id":"https:\/\/djangostars.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#primaryimage"},"image":{"@id":"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#primaryimage"},"thumbnailUrl":"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2021\/12\/What-and-How-to-Test-with-Jest-and-Enzyme.-Full-instruction-on-React-Components-Testing.jpg","datePublished":"2018-09-03T14:23:05+00:00","dateModified":"2025-10-21T09:25:20+00:00","author":{"@id":"https:\/\/djangostars.com\/blog\/#\/schema\/person\/9c46d946e51c5e426ba3a13c642cc0d5"},"description":"Master unit testing in React with our comprehensive guide on Jest enzyme testing. Learn best practices and tips for effective Jest and Enzyme tests.","breadcrumb":{"@id":"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#primaryimage","url":"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2021\/12\/What-and-How-to-Test-with-Jest-and-Enzyme.-Full-instruction-on-React-Components-Testing.jpg","contentUrl":"https:\/\/djangostars.com\/blog\/wp-content\/uploads\/2021\/12\/What-and-How-to-Test-with-Jest-and-Enzyme.-Full-instruction-on-React-Components-Testing.jpg","width":1440,"height":620,"caption":"What-and-How-to-Test-with-Jest-and-Enzyme"},{"@type":"BreadcrumbList","@id":"https:\/\/djangostars.com\/blog\/jest-enzyme-react-unit-testing\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/djangostars.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Unit Testing in React: Full Guide on Jest and Enzyme Testing"}]},{"@type":"WebSite","@id":"https:\/\/djangostars.com\/blog\/#website","url":"https:\/\/djangostars.com\/blog\/","name":"Software Development Blog &amp; IT Tech Insights | Django Stars","description":"Welcome behind the scenes of software product development. We share our best practices, tech solutions, management tips, and every useful insight we\u2018ve got while working on our projects.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/djangostars.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/djangostars.com\/blog\/#\/schema\/person\/9c46d946e51c5e426ba3a13c642cc0d5","name":"Alyona Pysarenko","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/djangostars.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/a15268f619d10a27871d8fa2db4cb2a8cc2e444e78aa3a899a1e539e5474a5ba?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a15268f619d10a27871d8fa2db4cb2a8cc2e444e78aa3a899a1e539e5474a5ba?s=96&d=mm&r=g","caption":"Alyona Pysarenko"},"sameAs":["https:\/\/www.linkedin.com\/in\/nedelchenko-alyona-2663bb78\/"],"url":"https:\/\/djangostars.com\/blog\/author\/alona-pysarenko\/"}]}},"_links":{"self":[{"href":"https:\/\/djangostars.com\/blog\/wp-json\/wp\/v2\/posts\/124","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/djangostars.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/djangostars.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/djangostars.com\/blog\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/djangostars.com\/blog\/wp-json\/wp\/v2\/comments?post=124"}],"version-history":[{"count":22,"href":"https:\/\/djangostars.com\/blog\/wp-json\/wp\/v2\/posts\/124\/revisions"}],"predecessor-version":[{"id":9882,"href":"https:\/\/djangostars.com\/blog\/wp-json\/wp\/v2\/posts\/124\/revisions\/9882"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/djangostars.com\/blog\/wp-json\/wp\/v2\/media\/3553"}],"wp:attachment":[{"href":"https:\/\/djangostars.com\/blog\/wp-json\/wp\/v2\/media?parent=124"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/djangostars.com\/blog\/wp-json\/wp\/v2\/categories?post=124"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/djangostars.com\/blog\/wp-json\/wp\/v2\/tags?post=124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}