<?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: Nico Amabile</title>
    <description>The latest articles on Forem by Nico Amabile (@nicolasamabile).</description>
    <link>https://forem.com/nicolasamabile</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%2F50265%2Fa08df7cf-8e52-4b80-8c76-ea5bd4285593.jpeg</url>
      <title>Forem: Nico Amabile</title>
      <link>https://forem.com/nicolasamabile</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nicolasamabile"/>
    <language>en</language>
    <item>
      <title>What programming best practice do you disagree with?</title>
      <dc:creator>Nico Amabile</dc:creator>
      <pubDate>Thu, 06 Jun 2019 23:57:00 +0000</pubDate>
      <link>https://forem.com/nicolasamabile/what-programming-best-practice-do-you-disagree-with-2pf6</link>
      <guid>https://forem.com/nicolasamabile/what-programming-best-practice-do-you-disagree-with-2pf6</guid>
      <description>&lt;p&gt;I've been recently asked this question in an interview and this was my answer:&lt;/p&gt;

&lt;h3&gt;
  
  
  Pure unit tests and shallow rendering idea
&lt;/h3&gt;

&lt;p&gt;For ReactJS in particular, there are many testing libraries that allow you to do shallow rendering (&lt;a href="https://airbnb.io/enzyme/" rel="noopener noreferrer"&gt;enzyme&lt;/a&gt; for example), that means that if you have a composed component, the test won’t actually render that inner component so you can’t make assertions on that. If you want to cover those internal components you need to write specific tests for each part.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div&amp;gt;
   &amp;lt;Form&amp;gt;
      &amp;lt;Username /&amp;gt;
      &amp;lt;Email /&amp;gt;
   &amp;lt;/Form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this structure, if you want to write a test for this component, the first &lt;code&gt;div&lt;/code&gt; will be rendered but the custom &lt;code&gt;Form&lt;/code&gt; component won’t, neither the &lt;code&gt;Username&lt;/code&gt; and &lt;code&gt;Email&lt;/code&gt; components, they will be mocked. You will have to test them individually, which follows the pure unit testing idea, but you can’t ensure that the components work ok together.&lt;br&gt;
If you follow this pattern, you will soon end up with a set of pure unit tests that are really confusing and hard to follow.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-965052178267176960-643" src="https://platform.twitter.com/embed/Tweet.html?id=965052178267176960"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-965052178267176960-643');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=965052178267176960&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tests should resemble the way the software is used.&lt;/strong&gt; Even though is not pure unit tests (technically you can call it integration test), at the end of the day the only thing that matters is that you can ship your app with confidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/kentcdodds" rel="noopener noreferrer"&gt;@kentcdodds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://frontendmasters.com/courses/testing-react/" rel="noopener noreferrer"&gt;Testing React Applications, v2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Image by &lt;a href="https://pixabay.com/users/geralt-9301/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=3808487" rel="noopener noreferrer"&gt;Gerd Altmann&lt;/a&gt;from &lt;a href="https://pixabay.com/?utm_source=link-attribution&amp;amp;utm_medium=referral&amp;amp;utm_campaign=image&amp;amp;utm_content=3808487" rel="noopener noreferrer"&gt;Pixabay&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>programming</category>
    </item>
    <item>
      <title>Why you should cleanup after render</title>
      <dc:creator>Nico Amabile</dc:creator>
      <pubDate>Tue, 28 May 2019 01:17:41 +0000</pubDate>
      <link>https://forem.com/nicolasamabile/why-you-should-cleanup-after-render-4aff</link>
      <guid>https://forem.com/nicolasamabile/why-you-should-cleanup-after-render-4aff</guid>
      <description>&lt;p&gt;I spent some time today debugging a simple &lt;a href="https://github.com/facebook/jest" rel="noopener noreferrer"&gt;jest&lt;/a&gt; test with &lt;a href="https://github.com/testing-library/react-testing-library" rel="noopener noreferrer"&gt;react-testing-library&lt;/a&gt;. I run into some issues and I couldn't easily figure out what was going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;For a very simple component I had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Snapshot test&lt;/li&gt;
&lt;li&gt;Some basic interaction tests that work correctly &lt;strong&gt;only if I run them separately&lt;/strong&gt; 😒&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I created this example to illustrate the idea:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

const Google = ({ onSubmit }) =&amp;gt; {
  const [text, setText] = useState('')
  return (
    &amp;lt;Fragment&amp;gt;
      &amp;lt;input
        data-testid='textbox'
        type='text'
        value={text}
        onChange={({ target: { value }}) =&amp;gt; setText(value)} /&amp;gt;

        &amp;lt;button
          data-testid='btn'
          onClick={() =&amp;gt; {
            if (text) {
              onSubmit(text)
              setText('')
            }
        }}&amp;gt;
          Search
        &amp;lt;/button&amp;gt;
    &amp;lt;/Fragment&amp;gt;
  )
}


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

&lt;/div&gt;

&lt;p&gt;And the tests:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { render, fireEvent } from 'react-testing-library'

describe('Google tests', () =&amp;gt; {
  test('It renders corectly', () =&amp;gt; {
    const { container } = render(&amp;lt;Google /&amp;gt;)
    expect(container.firstChild).toMatchSnapshot()
  })

  test('Search with empty value', () =&amp;gt; {
    const onSubmit = jest.fn()
    const { container, getByTestId } = render(&amp;lt;Google onSubmit={onSubmit}/&amp;gt;)
    const button = getByTestId('btn')
    fireEvent.click(button)
    expect(onSubmit).not.toBeCalled()
  })

  test('Seach with valid value', () =&amp;gt; {
    const onSubmit = jest.fn()
    const text = 'Example'
    const { container, getByTestId } = render(&amp;lt;Google onSubmit={onSubmit}/&amp;gt;)
    const textbox = getByTestId('textbox')
    fireEvent.change(textbox, { target: { value: text }})
    const button = getByTestId('btn')
    fireEvent.click(button)
    expect(onSubmit).toBeCalledWith(text)
  })
})



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

&lt;/div&gt;

&lt;p&gt;If I run this, I get this error:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgbi7wzn65pt0ndjuc7ss.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgbi7wzn65pt0ndjuc7ss.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clearly, I was sending a function for that particular test ('Search with valid value'). Typo maybe? 🤔&lt;br&gt;
My first reaction was to add &lt;code&gt;.only&lt;/code&gt; to the test and focus on that particular problem. Guess what, it worked 😒&lt;/p&gt;

&lt;p&gt;I spent some time debugging it until I realize that the failing test was using the component instance I created for the first snapshot test (the one that doesn't have the click handler) 🤯&lt;br&gt;
How the hell did that happen? &lt;/p&gt;

&lt;p&gt;From the &lt;a href="https://testing-library.com/docs/react-testing-library/api#cleanup" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;:&lt;br&gt;
&lt;em&gt;"Failing to call cleanup when you've called render could result in a memory leak and tests which are not "idempotent" (which can lead to difficult to debug errors in your tests)."&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;It was as simple as using &lt;code&gt;cleanup&lt;/code&gt; from &lt;code&gt;'react-testing-library'&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { render, fireEvent, cleanup } from 'react-testing-library'

describe('Google tests', () =&amp;gt; {
  beforeEach(cleanup)
  ...
})


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://repl.it/@NicolasAmabile/React-Testing-Example" rel="noopener noreferrer"&gt;Here&lt;/a&gt; you have a repl.it with the example. &lt;/p&gt;

&lt;p&gt;Hopefully, this will save you some debugging time 👍&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://www.pexels.com/@karatara-278139" rel="noopener noreferrer"&gt;karatara&lt;/a&gt; from &lt;a href="https://www.pexels.com/photo/male-statue-decor-931317/" rel="noopener noreferrer"&gt;Pexels&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>jest</category>
      <category>testing</category>
      <category>reacttestinglibrary</category>
    </item>
    <item>
      <title>React.Fragment, the only child</title>
      <dc:creator>Nico Amabile</dc:creator>
      <pubDate>Sun, 21 Apr 2019 18:08:16 +0000</pubDate>
      <link>https://forem.com/nicolasamabile/react-fragment-the-only-child-612</link>
      <guid>https://forem.com/nicolasamabile/react-fragment-the-only-child-612</guid>
      <description>&lt;p&gt;This is a short post about some issues I had while building a wizard component in ReactJS.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can't reference a "falsy" child while using &lt;code&gt;React.cloneElement&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;React.Fragment&lt;/code&gt; returns a single child.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the beginning my wizard instance looked something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Wizard&amp;gt;
  &amp;lt;Step1 /&amp;gt;
  &amp;lt;Step2 /&amp;gt;
  &amp;lt;Step3 /&amp;gt;
  &amp;lt;Step4 /&amp;gt;
  &amp;lt;Step5 /&amp;gt;
&amp;lt;/Wizard&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Behind the scenes, the component will only render the current step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;render () {
  const { children } = this.props
  const { activeStep } = this.state
  const extraProps = {...} // Some extra info I need on each step.
  return (
    …
    {React.cloneElement(children[activeStep], extraProps)}
    …
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Based on some business rules, I wanted to hide/show some steps, so my wizard instance will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;renderStep2 () {
  if (conditionForStep2) {
    return &amp;lt;Step2 /&amp;gt;
  }
}
render () {
  return ( 
    &amp;lt;Wizard&amp;gt;
      &amp;lt;Step1 /&amp;gt;
      {this.renderStep2()}
      &amp;lt;Step3 /&amp;gt;
      {conditionForStep4 &amp;amp;&amp;amp; &amp;lt;Step4 /&amp;gt;}
      &amp;lt;Step5 /&amp;gt;
    &amp;lt;/Wizard&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those expressions evaluate to undefined for &lt;code&gt;Step2&lt;/code&gt; and false for &lt;code&gt;Step4&lt;/code&gt;, and any of those values can be used as a valid child when doing &lt;code&gt;React.cloneElement(children[activeStep], extraProps)&lt;/code&gt; where &lt;code&gt;activeStep&lt;/code&gt; is the index of &lt;code&gt;Step2&lt;/code&gt; or &lt;code&gt;Step4&lt;/code&gt;, React will complain 😩 and also my index will be wrong.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq2xv4pxkx7y5x0vy4mck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq2xv4pxkx7y5x0vy4mck.png" alt="React error. Element type is invalid" width="800" height="105"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instead of using children directly, I created a function that returns only the "truthy" steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getChildren = children =&amp;gt; children.filter(child =&amp;gt; !!child)
And change my Wizard render function to something like this:
render () {
 const { children } = this.props
 const { activeStep } = this.state
 const filteredChildren = getChildren(children)
 return (
   …
   {React.cloneElement(filteredChildren[activeStep], extraProps)}
   …
 )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first problem solved 🎉&lt;/p&gt;

&lt;p&gt;I got to the point where I wanted to group some steps in order to simplify my logic. Let's say for example that I need to use the same condition for rendering &lt;code&gt;Step3&lt;/code&gt;, &lt;code&gt;Step4&lt;/code&gt; and &lt;code&gt;Step5&lt;/code&gt;, so I grouped them into a &lt;code&gt;React.Fragment&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;renderMoreSteps () {
  if (condition) {
    return (
      &amp;lt;Fragment&amp;gt;
        &amp;lt;Step3 /&amp;gt;
        &amp;lt;Step4 /&amp;gt;
        &amp;lt;Step5 /&amp;gt;
      &amp;lt;/Fragment&amp;gt;
    )
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And my Wizard instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Wizard&amp;gt;
  &amp;lt;Step1 /&amp;gt;
  &amp;lt;Step2 /&amp;gt;
  {this.renderMoreSteps()}
&amp;lt;/Wizard&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem: Even though Fragment is not represented as DOM elements, it returns a single child instead of individual child components.&lt;br&gt;
The solution: flatten children.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { isFragment } from 'react-is'
const flattenChildren = children =&amp;gt; {
  const result = []
  children.map(child =&amp;gt; {
    if (isFragment(child)) {
      result.push(…flattenChildren(child.props.children))
    } else {
      result.push(child)
    }
  })
  return result
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Updated getChildren function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getChildren = children =&amp;gt; flattenChildren(children).filter(child =&amp;gt; !!child &amp;amp;&amp;amp; !isEmpty(child))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For simplicity, I used &lt;a href="https://www.npmjs.com/package/react-is" rel="noopener noreferrer"&gt;react-is&lt;/a&gt;, but the implementation is straight forward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function isFragment (object) {
  return typeOf(object) === REACT_FRAGMENT_TYPE
}
const REACT_FRAGMENT_TYPE = hasSymbol
  ? Symbol.for('react.fragment')
  : 0xeacb;
const hasSymbol = typeof Symbol === 'function' &amp;amp;&amp;amp; Symbol.for;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope this helps!&lt;br&gt;
All comments are welcomed.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>fragments</category>
    </item>
  </channel>
</rss>
