<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Richard Igbiriki</title>
    <description>The latest articles on Forem by Richard Igbiriki (@richardigbiriki).</description>
    <link>https://forem.com/richardigbiriki</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F233792%2F340a76d8-04c9-47bf-ad1e-37ab71b8d6b9.jpg</url>
      <title>Forem: Richard Igbiriki</title>
      <link>https://forem.com/richardigbiriki</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/richardigbiriki"/>
    <language>en</language>
    <item>
      <title>Building Consistent RESTful APIs</title>
      <dc:creator>Richard Igbiriki</dc:creator>
      <pubDate>Tue, 14 Apr 2020 00:29:38 +0000</pubDate>
      <link>https://forem.com/richardigbiriki/building-consistent-restful-apis-nik</link>
      <guid>https://forem.com/richardigbiriki/building-consistent-restful-apis-nik</guid>
      <description>&lt;p&gt;When it comes to building RESTful APIs, the applications are limitless while the standards and/or best practices remain the same across different stacks. This is an attempt to portray some of those standards and best practices (highly opinionated). &lt;/p&gt;

&lt;h2&gt;
  
  
  Authorization
&lt;/h2&gt;

&lt;p&gt;Representational State Transfer (REST) effectively invalidates sessions and as such, our applications require another way of authorizing users trying to access it. One of the most commonly used tools for authorization is &lt;a href="https://jwt.io/introduction/"&gt;JSON Web Tokens-JWT&lt;/a&gt;. Once a user logs in or signs up to our application, a token is assigned to that user for a period of time (the length depends largely on the security concerns of your application). A good practice is to add a unique identifier to the token so each request to our application can serve the particular user making that request without asking for extra parameters from the user. &lt;/p&gt;

&lt;p&gt;For example, if I am logged in using JWT, and I attempt to retrieve all transactions I have made on the application, the application should be able to provide ONLY my transactions based on my JWT authorization token.&lt;/p&gt;

&lt;p&gt;Without going into implementation details, one can achieve this by having a service intercept incoming requests, process the JWT token and set a current_user object or variable accessible throughout the application. &lt;/p&gt;

&lt;h2&gt;
  
  
  Resources, Actions, and HTTP Methods
&lt;/h2&gt;

&lt;p&gt;In REST we have resources, which can represent database tables, e.g companies, users, posts, messages, etc. Every resource has a list of actions that can be performed on it. These actions are determined by the HTTP method on each request to that resource. HTTP Methods are also referred to as HTTP VERBS because they perform/determine actions. Given a resource, &lt;em&gt;transactions&lt;/em&gt;, below are some of the most common corresponding HTTP Methods and actions. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GET - /transactions&lt;/strong&gt; (get all transactions)&lt;br&gt;
&lt;strong&gt;GET - /transactions/:id&lt;/strong&gt; (get a single transaction)&lt;br&gt;
&lt;strong&gt;POST - /transactions&lt;/strong&gt; (create a new transaction)&lt;br&gt;
&lt;strong&gt;PATCH - /transactions/:id&lt;/strong&gt; (update parts of a transaction)&lt;br&gt;
&lt;strong&gt;PUT - /transactions/:id&lt;/strong&gt; (update a transaction)&lt;br&gt;
&lt;strong&gt;DELETE - /transactions/:id&lt;/strong&gt; (delete a transaction)&lt;/p&gt;

&lt;p&gt;Depending on the scale of your application, you may need to extend the actions available on your resource by custom endpoints. Custom endpoints can either affect the entire resource (collection) or a member of the resource. For actions affecting the collection, it is as follows:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GET - /transactions/users&lt;/strong&gt; (get all users that have made transactions)&lt;br&gt;
&lt;strong&gt;GET - /transactions/failed&lt;/strong&gt; (get all failed transactions)&lt;/p&gt;

&lt;p&gt;For a member, assuming we have a separate but related resource for a transaction details:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GET - /transactions/:id/details&lt;/strong&gt; (get the details of a transaction) &lt;br&gt;
&lt;strong&gt;POST -/transactions/:id/details&lt;/strong&gt; (create details for a transaction)&lt;br&gt;
&lt;strong&gt;PUT -/transactions/:id/details&lt;/strong&gt; (update the details of a transaction).&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP Response Status
&lt;/h2&gt;

&lt;p&gt;The response and status returned from every request depending on the action being performed and the status of the action. A &lt;strong&gt;POST&lt;/strong&gt; request should never return a 204 (No Content) and a &lt;strong&gt;DELETE&lt;/strong&gt; request should never return 201 (Created). Below are the most common responses based on their request and status. &lt;/p&gt;

&lt;h4&gt;
  
  
  200 - OK
&lt;/h4&gt;

&lt;p&gt;The request was completed. You can't go wrong with a 200 status if the action requested for was completed successfully however, there might be more appropriate status messages depending on the action. &lt;/p&gt;

&lt;h3&gt;
  
  
  201 - Created
&lt;/h3&gt;

&lt;p&gt;Ideally, this should be returned whenever a new object is created (mostly with a &lt;strong&gt;POST&lt;/strong&gt; request) alongside the object that was created. Returning the object that was created is a personal preference as it grants access to the newly created object immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  204 - No Content
&lt;/h3&gt;

&lt;p&gt;This can and &lt;em&gt;should&lt;/em&gt; be returned after a &lt;strong&gt;DELETE&lt;/strong&gt; has been completed on an object. &lt;/p&gt;

&lt;h3&gt;
  
  
  401 - Unauthorized
&lt;/h3&gt;

&lt;p&gt;This is appropriate when a user tries an action that requires authorization but the request doesn't possess that authorization. &lt;/p&gt;

&lt;h3&gt;
  
  
  404 - Not Found
&lt;/h3&gt;

&lt;p&gt;Highly unlikely but if a user requests for a resource that doesn't exist, 404 is the appropriate status to respond with. Albeit based on your use case, returning &lt;em&gt;200 - ok&lt;/em&gt; and an empty result may be more appropriate.  &lt;/p&gt;

</description>
      <category>rails</category>
      <category>node</category>
      <category>php</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Refactoring React Components for Testability with Jest and Enzyme</title>
      <dc:creator>Richard Igbiriki</dc:creator>
      <pubDate>Sun, 22 Sep 2019 10:55:15 +0000</pubDate>
      <link>https://forem.com/richardigbiriki/refactoring-react-components-for-testability-with-jest-and-enzyme-m7b</link>
      <guid>https://forem.com/richardigbiriki/refactoring-react-components-for-testability-with-jest-and-enzyme-m7b</guid>
      <description>&lt;h3&gt;
  
  
  Disclaimer
&lt;/h3&gt;

&lt;p&gt;I cannot affirm or deny that this post is a continuation of my previous post: &lt;a href="https://dev.to/richardigbiriki/testing-your-first-react-component-with-jest-and-enzyme-p38"&gt;Testing Your First React Component with Jest and Enzyme&lt;/a&gt;, but if this is your first read on testing react components, I do politely suggest you see that one first. &lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Testing your react components is a thrilling exercise (in my experience), however, it can take a swift turn if your components are &lt;code&gt;large&lt;/code&gt; and rippled with &lt;code&gt;state&lt;/code&gt;. Consequently, it is considered a good (perhaps best?) practice to split components into smaller independent components...preferably pure components. Using pure components prevents unnecessary side effects that can occur in the component lifecycle methods. In this post, we will walk through splitting a component into smaller pure components and writing tests for those components. &lt;/p&gt;

&lt;p&gt;Let's get started.&lt;/p&gt;

&lt;h3&gt;
  
  
  Our Component
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fivstwghmi0717d8u93wu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fivstwghmi0717d8u93wu.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Observations
&lt;/h4&gt;

&lt;p&gt;In this component, we can see that we have a box for each program. This is a testable unit and should be its own component. We also have a 'Programs' text and a 'Create New' button in the subheader, this can also be moved into its own component. Keeping in mind this possible splits, let's see what the initial implementation can look like. We will ONLY view the &lt;code&gt;render&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
const { loading, message, programs } = this.state;

&amp;lt;div loading={loading} message={message} programs={programs}  className="container jumbo-header"&amp;gt;
        &amp;lt;div className="jumbo-box"&amp;gt;
            &amp;lt;div className="jumbo"&amp;gt;
            &amp;lt;p id="title" className="ml-3 text"&amp;gt;Programs&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
         &amp;lt;/div&amp;gt;

        {/* show message if there is a status mesage */}
        {message &amp;amp;&amp;amp; &amp;lt;div className='text-center'&amp;gt;
            &amp;lt;h5 id="message" className='text-info'&amp;gt; {message} &amp;lt;/h5&amp;gt;
        &amp;lt;/div&amp;gt;}

        {/* If fetching programs, show loading spinner */}
        {loading &amp;amp;&amp;amp; &amp;lt;Spinner animation="grow" variant="info" /&amp;gt;}

        &amp;lt;Container className="mt-3"&amp;gt;
            &amp;lt;div className="admin-button" style={{height:'3rem'}}&amp;gt;
                &amp;lt;Link id="new-link" to='/programs/new'&amp;gt;
                    &amp;lt;Button id='new-button' className="create float-right"&amp;gt;Create New&amp;lt;/Button&amp;gt;
                &amp;lt;/Link&amp;gt;
            &amp;lt;/div&amp;gt;

            {/* return all programs as Card items if they exist */}
            { programs &amp;amp;&amp;amp; programs.map((data, i) =&amp;gt;
                &amp;lt;Card data={data} key={data.id} className="pro-box ml-5 shadow p-2 mt-4 rounded float-left" border="light" style={{width: '30rem'}}&amp;gt;
                   &amp;lt;h4 id="title" className="text-center mt-2"&amp;gt;{data.title}&amp;lt;/h4&amp;gt;
                   &amp;lt;div className="pro-text d-flex pt-5 text-center"&amp;gt;
                      &amp;lt;p id="length" className="ml-5 text-center"&amp;gt;Duration: {data.length}&amp;lt;/p&amp;gt;
                      &amp;lt;p id="instructor" className="ml-5"&amp;gt;Instructor: {data.instructor}&amp;lt;/p&amp;gt;
                  &amp;lt;/div&amp;gt;
                      &amp;lt;p className="pro-anchor text-center pt-4"&amp;gt;VIEW&amp;lt;/p&amp;gt;
                &amp;lt;/Card&amp;gt;
            )}
        &amp;lt;/Container&amp;gt;
    &amp;lt;/div&amp;gt;

)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we have a &lt;strong&gt;CORRECT&lt;/strong&gt; but large single implementation of the UI we were given. However, this implementation makes testing the programs &lt;code&gt;Card&lt;/code&gt;, for instance, a tidbit more difficult. If you can somehow circumvent that difficulty, testing the component as it is will result in unnecessary side effects, as I earlier mentioned. &lt;/p&gt;

&lt;p&gt;Following our initial observation, let us split this render method into simpler pure components. &lt;/p&gt;

&lt;h3&gt;
  
  
  Main Component
&lt;/h3&gt;

&lt;p&gt;Our main component above will be refactored to return a secondary component as shown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;render() {
        //Programs component is more easily testable as a pure function
        const { programs, message, loading } = this.state;
        return(
            &amp;lt;ProgramsComponent programs={programs} message={message} loading={loading} /&amp;gt;
        )
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Moving on...&lt;/p&gt;

&lt;h3&gt;
  
  
  Programs Component
&lt;/h3&gt;

&lt;p&gt;Our programs component will render the subheader, the spinner, and a message if any. It will also attempt to render a separate &lt;code&gt;Item&lt;/code&gt; component that represents a program for every available program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const ProgramsComponent = ({ programs, message, loading }) =&amp;gt; (

    &amp;lt;div loading={loading} message={message} programs={programs}  className="container jumbo-header"&amp;gt;
        &amp;lt;div className="jumbo-box"&amp;gt;
            &amp;lt;div className="jumbo"&amp;gt;
            &amp;lt;p id="title" className="ml-3 text"&amp;gt;Programs&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
         &amp;lt;/div&amp;gt;

        {message &amp;amp;&amp;amp; &amp;lt;div className='text-center'&amp;gt;&amp;lt;h5 id="message" className='text-info'&amp;gt; {message} &amp;lt;/h5&amp;gt;&amp;lt;/div&amp;gt;}

        {loading &amp;amp;&amp;amp; &amp;lt;Spinner animation="grow" variant="info" /&amp;gt;}

        &amp;lt;Container className="mt-3"&amp;gt;
            &amp;lt;div className="admin-button" style={{height:'3rem'}}&amp;gt;
                &amp;lt;Link id="new-link" to='/programs/new'&amp;gt;
                    &amp;lt;Button id='new-button' className="create float-right"&amp;gt;Create New&amp;lt;/Button&amp;gt;
                &amp;lt;/Link&amp;gt;
            &amp;lt;/div&amp;gt;

             {/* Move program details to another component */}
            { programs &amp;amp;&amp;amp; programs.map((data, i) =&amp;gt;
                &amp;lt;Item key={data._id} data={data} /&amp;gt;
            )}

        &amp;lt;/Container&amp;gt;
    &amp;lt;/div&amp;gt;
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Moving on to our final component...&lt;/p&gt;

&lt;h3&gt;
  
  
  Item Component
&lt;/h3&gt;

&lt;p&gt;Our item component will only be responsible for rendering a program. This enables us to test this component as a unit (re: unit testing). Did I just explain &lt;code&gt;unit testing&lt;/code&gt; as a side effect of this post? Interesting! &lt;/p&gt;

&lt;p&gt;Here is our Item component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Item = ({ data }) =&amp;gt; (
    &amp;lt;Card data={data} key={data.id} className="pro-box ml-5 shadow p-2 mt-4 rounded float-left" border="light" style={{width: '30rem'}}&amp;gt;
        &amp;lt;h4 id="title" className="text-center mt-2"&amp;gt;{data.title}&amp;lt;/h4&amp;gt;
        &amp;lt;div className="pro-text d-flex pt-5 text-center"&amp;gt;
        &amp;lt;p id="length" className="ml-5 text-center"&amp;gt;Duration: {data.length}&amp;lt;/p&amp;gt;
        &amp;lt;p id="instructor" className="ml-5"&amp;gt;Instructor: {data.instructor}&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;p className="pro-anchor text-center pt-4"&amp;gt;VIEW&amp;lt;/p&amp;gt;
    &amp;lt;/Card&amp;gt;
);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have successfully divided out large component into two smaller pure components that can be tested individually. For the sake of brevity (this is already getting too long), we will be drastically limiting our test coverage in this post. &lt;/p&gt;

&lt;h3&gt;
  
  
  Testing Our Components
&lt;/h3&gt;

&lt;p&gt;Our unit tests can be divided into at least three stages. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;When the component is fetching programs. Loading stage. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the component has finished loading but has no content. Empty stage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When the component has finished loading, has no message, but has content. This can be further split to testing scenarios of one item or multiple items. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tests for our Item component.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Yeah, I know, this may already sound like so much work. Doh. However, we did agree to keep it short and simple so below are the tests for the different stages. &lt;/p&gt;

&lt;h4&gt;
  
  
  Stage 1 and 2: Loadin and Empty Content
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   describe('tests general requirements and an loading component', () =&amp;gt; {

             //Start with an empty loading component
             const wrapper = shallow(&amp;lt;ProgramsComponent loading={true} message={null} programs={[]} /&amp;gt;);

            describe('tests general component requirements', () =&amp;gt; {

                it('should have page title', ()=&amp;gt; {
                    expect(wrapper.find('#title')).toHaveLength(1);
                    expect(wrapper.find('#title').text()).toEqual('Programs');
                });

                //...More tests for button and Link

            });

            describe('tests empty program', () =&amp;gt; {
                it('should be loading', () =&amp;gt; {
                    expect(wrapper.props().loading).toEqual(true);
                });

                it('should have a spinner', () =&amp;gt; {
                    expect(wrapper.find('Spinner')).toHaveLength(1);
                });

                it('should not have Item', () =&amp;gt; {
                    expect(wrapper.props().programs.length).toEqual(0);
                    expect(wrapper.find('Item')).toHaveLength(0);
                });

               //...Test for no message

            });

        });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Stage 3:  Available Content
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       describe('tests component with multiple programs', () =&amp;gt; {
            const programs=[
                {
                    _id:1,
                    title: 'Web Development',
                    length: '3 Months',
                    instructor: 'Richard Igbiriki'
                },
                {
                    _id:2,
                    title: 'Mobile Development',
                    length: '3 Months',
                    instructor: 'Richard Igbiriki'
                },
                {
                    _id:3,
                    title: 'Software Development',
                    length: '3 Months',
                    instructor: 'Richard Igbiriki'
                }
            ];
            const wrapper = shallow(&amp;lt;ProgramsComponent loading={false} message={null} programs={programs} /&amp;gt;);

            it('should have three Items', () =&amp;gt; {
                expect(wrapper.find('Item')).toHaveLength(3);
            });

            it('should update items on props update', () =&amp;gt; {
                //remove one item
                const i = programs.pop();
                wrapper.setProps({ programs });
                expect(wrapper.find('Item')).toHaveLength(2);
                //add item
                programs.push(i);
                wrapper.setProps({ programs });
                expect(wrapper.find('Item')).toHaveLength(3);
            });
            //...More tests
        });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Stage 4: Item Component
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    describe('Tests Item component', () =&amp;gt; {
        const data = {
            _id:1,
            title: 'Web Development',
            length: '3 Months',
            instructor: 'Richard Igbiriki'
        }
        const wrapper = shallow(&amp;lt;Item data={data} /&amp;gt;);

        it('should have data props', () =&amp;gt; {
            expect(wrapper.props().data).toBeDefined();
        });

        it('should have a title', () =&amp;gt; {
            expect(wrapper.find('#title')).toHaveLength(1);
            expect(wrapper.find('#title').text()).toEqual(data.title);
        });

        it('should have a length', () =&amp;gt; {
            expect(wrapper.find('#length')).toHaveLength(1);
            expect(wrapper.find('#length').text()).toEqual('Duration: '+data.length);
        });

        it('should have an instructor', () =&amp;gt; {
            expect(wrapper.find('#instructor')).toHaveLength(1);
            expect(wrapper.find('#instructor').text()).toEqual('Instructor: '+data.instructor);
        });
    });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation: Testing Matchers
&lt;/h3&gt;

&lt;p&gt;In all our tests, we used between 3 to 5 &lt;a href="https://airbnb.io/enzyme/docs/api/shallow.html" rel="noopener noreferrer"&gt;Matchers&lt;/a&gt; and 2 to 3 &lt;a href="https://jestjs.io/docs/en/expect" rel="noopener noreferrer"&gt;methods on expect&lt;/a&gt; for comparison.&lt;/p&gt;

&lt;h4&gt;
  
  
  Matchers
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.find:&lt;/strong&gt; takes a selector and finds matching nodes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.props&lt;/strong&gt; gets the props set on the node. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.setProps&lt;/strong&gt; updates the props on the node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.text&lt;/strong&gt; returns the text on the current node. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Explanation: &lt;code&gt;expect&lt;/code&gt; methods
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.toHaveLength(n)&lt;/strong&gt; expects the returned value to have an element of length or size n.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;.toEqual(variable)&lt;/strong&gt; expects the returned value to be equal to &lt;em&gt;variable&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Yay!!! We are done. &lt;/p&gt;

&lt;p&gt;This was longer than I anticipated but once again, I hope it was as fun for you reading and trying as it was for me writing it.&lt;/p&gt;

&lt;p&gt;For those that do not follow me on Twitter, these posts contain active projects that I and my team are currently working on that is why I do not have links to any github repo. I will continue to write as the need arises. &lt;/p&gt;

&lt;p&gt;Thank you.   &lt;/p&gt;

</description>
      <category>react</category>
      <category>testing</category>
      <category>javascript</category>
      <category>td</category>
    </item>
    <item>
      <title>Testing your first React Component with Jest and Enzyme</title>
      <dc:creator>Richard Igbiriki</dc:creator>
      <pubDate>Sat, 21 Sep 2019 13:08:53 +0000</pubDate>
      <link>https://forem.com/richardigbiriki/testing-your-first-react-component-with-jest-and-enzyme-p38</link>
      <guid>https://forem.com/richardigbiriki/testing-your-first-react-component-with-jest-and-enzyme-p38</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;If you've spent three months writing code in recent times then you must have come across the concept of 'testing' or 'test-driven development' (TDD). It is considered a best practice to test your code to ensure that it works as you expect it to work under any circumstance. In my experience, testing, for a lack of a better word, 'forces' us to code better (think readability, scalability).&lt;/p&gt;

&lt;p&gt;Writing testable code is a skill in itself. Unit testing, for instance, requires splitting React components into smaller (preferably, pure components) components.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing Environment Setup
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;create-react-app&lt;/code&gt; sets up React with jest as the default testing library. To enable us to test react components, we need to add &lt;code&gt;enzyme&lt;/code&gt; to our project's development dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add enzyme enzyme-adapter-react-16 --dev OR npm install enzyme enzyme-adapter-react-16 --save-dev

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add &lt;code&gt;setupTests.js&lt;/code&gt; to your &lt;code&gt;src&lt;/code&gt; directory. Add the setup code below to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// /src/setupTests.js

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jest automatically finds test files that have the suffix &lt;code&gt;*.test.js&lt;/code&gt; or &lt;code&gt;*.spec.js&lt;/code&gt;. Another option is to place all test code into a &lt;code&gt;_tests_&lt;/code&gt; folder. Jest will find and run all test files regardless of relative directory position to &lt;code&gt;src&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Syntax
&lt;/h3&gt;

&lt;p&gt;As I like to put it, tests are just conditionals. True OR False. A binary comparison between an actual and expected value. For instance, we expect 1 to equal 1. Or we expect 1 + 1 to equal 2. This is precisely how we test our components. By comparing an expected outcome to the actual outcome. &lt;/p&gt;

&lt;p&gt;Using jest we:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;expect(actual).toEqual(expected); 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OR&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;expect(actual).not.toEqual(expected); 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Enzyme provides a list of &lt;a href="https://airbnb.io/enzyme/docs/api/shallow.html" rel="noopener noreferrer"&gt;Matchers&lt;/a&gt; and Jest provides &lt;a href="https://jestjs.io/docs/en/expect" rel="noopener noreferrer"&gt;methods of comparisons for expect&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Testing Our Component
&lt;/h3&gt;

&lt;p&gt;Below is the component we will be testing&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fq3nihjtl58cr44srn8g2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fq3nihjtl58cr44srn8g2.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will keep our tests for this component simple...for brevity (or so I claim). &lt;/p&gt;

&lt;p&gt;For this component, I want to test:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Presence of input with email id&lt;/li&gt;
&lt;li&gt;Presence of input with password id&lt;/li&gt;
&lt;li&gt;Presence of an avatar icon using the &lt;code&gt;avatar&lt;/code&gt; class.&lt;/li&gt;
&lt;li&gt;Presence of a button with 'Login' text.&lt;/li&gt;
&lt;li&gt;The validation function that ensures email and password is not empty.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;h3&gt;
  
  
  Tests
&lt;/h3&gt;

&lt;p&gt;Here is our &lt;code&gt;Login.test.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { shallow } from 'enzyme';
import Login from './Pages/LogIn';
import { validateEmailAndPasswordPresence } from '../extra/validations';
    describe('Login component tests', ()=&amp;gt; {
        const wrapper = shallow(&amp;lt;Login /&amp;gt;);

        it('should have a btn component', ()=&amp;gt; {

            //There should be only one button
            expect(wrapper.find('Button')).toHaveLength(1);

            //Button should be of type button
            expect(wrapper.find('Button')
            .type().defaultProps.type)
            .toEqual('button');

            //Button should have matching text
            expect(wrapper.find('Button').text()).toEqual('LOGIN');
        });

        it('should have input for email and password', ()=&amp;gt; {
            //Email and password input field should be present
            expect(wrapper.find('input#email')).toHaveLength(1);
            expect(wrapper.find('input#password')).toHaveLength(1);
        });


        it('should an avatar', ()=&amp;gt; {
            //Avatar should be present
            expect(wrapper.find('.avatar')).toHaveLength(1);
        });

        it('should have an empty email and password state var', ()=&amp;gt; {
            //Optionally test to check if password and email are empty strings on 
               setup
            expect(wrapper.state('email')).toEqual('');
            expect(wrapper.state('password')).toEqual('');
        });

        it('should test email and password presence', () =&amp;gt; {

             //should return true 
             expect(validateEmailAndPasswordPresence('email@email.com', 
             'password').toEqual(true);

             //should return false
              expect(validateEmailAndPasswordPresence('', 
             '').toEqual(false);
        });

    });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The button tested here is the button component from &lt;code&gt;react-bootstrap&lt;/code&gt;. Replace with your own button component. &lt;/p&gt;

&lt;h3&gt;
  
  
  Explanation
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;describe&lt;/code&gt; is used to describe what we are about to test. It is a wrapper function for tests concerning a particular component. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;it&lt;/code&gt; describes a particular test. I use &lt;code&gt;it&lt;/code&gt; as a should (comparison). So &lt;code&gt;it&lt;/code&gt; should have an avatar. Or &lt;code&gt;it&lt;/code&gt; should be true if email and password present.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To run your test, use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm test or yarn test

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in your project directory. All tests should fail. Yes!!! The joy of TDD. &lt;/p&gt;

&lt;h3&gt;
  
  
  Login Component
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import React, {Component} from 'react'
import {FaUserCircle} from 'react-icons/fa'
import {Form, Button} from 'react-bootstrap'
import { Redirect } from 'react-router-dom'

export default class Login extends Component {
    constructor() {
        super();
        this.state = {
            email: '',
            password: ''
        }
    }

    handleChange = (event) =&amp;gt; {
        this.setState({[event.target.name]:event.target.value});
    }

    login = async () =&amp;gt; {
        //login here
    }
    render () {
        return(
            &amp;lt;div className="container-fluid box mt-5"&amp;gt;
                &amp;lt;div className="loginbox shadow p-5"&amp;gt;
                    &amp;lt;FaUserCircle className="avatar" /&amp;gt;
                     &amp;lt;Form className="p-2 mt-5"&amp;gt;
                        &amp;lt;Form.Group className="mb-3"&amp;gt;
                            &amp;lt;Form.Control id="email" type="text" name="email" onChange={this.handleChange} placeholder="Email/Username" className="text-center" /&amp;gt;
                        &amp;lt;/Form.Group&amp;gt;
                        &amp;lt;Form.Group className="mb-3 mt-4"&amp;gt;
                            &amp;lt;Form.Control id="password" type="password" name="password" onChange={this.handleChange} placeholder="Password" className="text-center" /&amp;gt;
                        &amp;lt;/Form.Group&amp;gt;
                        &amp;lt;Form.Group className="Log-button"&amp;gt;
                            &amp;lt;Button onClick={this.login} className="btn" style={{width: '10rem'}}&amp;gt;LOGIN&amp;lt;/Button&amp;gt;
                        &amp;lt;/Form.Group&amp;gt;

                    &amp;lt;/Form&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;/div&amp;gt;
        )
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installing all the dependencies using &lt;code&gt;yarn' or&lt;/code&gt;npm`, rerun your tests and they should all PASS. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fanxpt45vkylnuo8m4fo1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fanxpt45vkylnuo8m4fo1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: There are more tests in the image above than covered here.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Test-Driven Development (TDD), Behaviour-Driven Development (BDD), Poverty-Driven Development (PDD), CLI-Drive Development (CDD), and whatever else exists all lead to one thing, a product. What matters is that we follow patterns and use best practices that suit our current development circle. &lt;/p&gt;

&lt;p&gt;I have been coding for a couple of years and just started writing tests, although I do wish I started earlier. If you do not think TDD is worth it, give it a few more days or months or years, see you when you finally decide. &lt;/p&gt;

</description>
      <category>react</category>
      <category>testing</category>
      <category>javascript</category>
      <category>tdd</category>
    </item>
  </channel>
</rss>
