<?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>DEV Community: Adriana Ferreira Lima Shikasho</title>
    <description>The latest articles on DEV Community by Adriana Ferreira Lima Shikasho (@dxwebster).</description>
    <link>https://dev.to/dxwebster</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%2F555657%2F5b4e57bf-bcc3-47fa-b11d-3bb47c3de58d.jpeg</url>
      <title>DEV Community: Adriana Ferreira Lima Shikasho</title>
      <link>https://dev.to/dxwebster</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dxwebster"/>
    <language>en</language>
    <item>
      <title>Olha que legal minha conversa com o ChatGPT sobre Polimorfismo no Javascript</title>
      <dc:creator>Adriana Ferreira Lima Shikasho</dc:creator>
      <pubDate>Mon, 15 May 2023 23:31:52 +0000</pubDate>
      <link>https://dev.to/dxwebster/olha-que-conversa-legal-que-tive-com-chatgpt-sobre-polimorfismo-no-javascript-26</link>
      <guid>https://dev.to/dxwebster/olha-que-conversa-legal-que-tive-com-chatgpt-sobre-polimorfismo-no-javascript-26</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🙋🏻‍♀️ Eu: - Me dê um exemplo de polimorfismo usando Javascript.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🤖 ChatGPT: - Claro! Aqui está um exemplo de polimorfismo em JavaScript:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Classe base&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;makeSound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O animal faz um som.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Subclasse que estende a classe Animal&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;makeSound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O cachorro late.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Subclasse que estende a classe Animal&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;makeSound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O gato mia.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Função que recebe um objeto Animal e chama o método makeSound&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;makeAnimalSound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;makeSound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Criando instâncias das classes Dog e Cat&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Whiskers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Chamando a função makeAnimalSound com diferentes objetos&lt;/span&gt;
&lt;span class="nx"&gt;makeAnimalSound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: "O cachorro late."&lt;/span&gt;
&lt;span class="nx"&gt;makeAnimalSound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: "O gato mia."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse exemplo, temos uma classe base chamada &lt;code&gt;Animal&lt;/code&gt; com um método &lt;code&gt;makeSound&lt;/code&gt;. Em seguida, temos duas subclasses, &lt;code&gt;Dog&lt;/code&gt; (cachorro) e &lt;code&gt;Cat&lt;/code&gt; (gato), que estendem a classe base &lt;code&gt;Animal&lt;/code&gt; e substituem o método &lt;code&gt;makeSound&lt;/code&gt; para produzir o som específico de cada animal.&lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;makeAnimalSound&lt;/code&gt; recebe um objeto do tipo &lt;code&gt;Animal&lt;/code&gt; (que pode ser uma instância de Dog ou Cat) e chama o método &lt;code&gt;makeSound&lt;/code&gt; do objeto. Dependendo do tipo do objeto passado, o método &lt;code&gt;makeSound&lt;/code&gt; apropriado será executado.&lt;/p&gt;

&lt;p&gt;Isso é &lt;strong&gt;polimorfismo&lt;/strong&gt;, onde diferentes objetos podem responder de maneira diferente ao mesmo método, permitindo um código mais flexível e reutilizável.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🙋🏻‍♀️ Eu: - É possível aplicar polimorfismo na programaçao funcional?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🤖 ChatGPT: - Na programação funcional, o conceito de &lt;strong&gt;polimorfismo&lt;/strong&gt; é um pouco diferente do exemplo anterior, pois não há classes ou herança como na programação orientada a objetos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No entanto, é possível obter um comportamento polimórfico usando &lt;strong&gt;funções de alta ordem (higher-order functions)&lt;/strong&gt; e passando funções como parâmetros.&lt;/p&gt;

&lt;p&gt;Aqui está uma adaptação do exemplo anterior para demonstrar o polimorfismo em programação funcional:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Função polimórfica que recebe uma função como argumento&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;makeAnimalSound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;animalFn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;animalFn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Funções específicas para diferentes sons de animais&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;dogSound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O cachorro late.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;catSound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O gato mia.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Utilizando a função polimórfica com diferentes funções&lt;/span&gt;
&lt;span class="nx"&gt;makeAnimalSound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dogSound&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: "O cachorro late."&lt;/span&gt;
&lt;span class="nx"&gt;makeAnimalSound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;catSound&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: "O gato mia."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, temos a função &lt;code&gt;makeAnimalSound&lt;/code&gt; que recebe uma &lt;strong&gt;função como argumento&lt;/strong&gt; (animalFn). Essa função é polimórfica, pois pode receber diferentes funções específicas para diferentes sons de animais.&lt;/p&gt;

&lt;p&gt;As funções &lt;code&gt;dogSound&lt;/code&gt; e &lt;code&gt;catSound&lt;/code&gt; são exemplos de funções específicas para diferentes sons de animais. Cada uma dessas funções produz um som específico quando é chamada.&lt;/p&gt;

&lt;p&gt;Ao chamar a função &lt;code&gt;makeAnimalSound&lt;/code&gt; com diferentes funções (dogSound e catSound), obtemos resultados diferentes, cada um correspondendo ao som específico do animal.&lt;/p&gt;

&lt;p&gt;Assim, conseguimos obter um &lt;strong&gt;comportamento polimórfico&lt;/strong&gt; ao passar diferentes funções para a função &lt;code&gt;makeAnimalSound&lt;/code&gt; na programação funcional.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🙋🏻‍♀️ Eu: - Podemos dizer então, que a classe é polimorfica quando recebe diferentes classes como argumento?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🤖 ChatGPT: - Sim, podemos dizer que uma classe é polimórfica quando ela recebe diferentes classes como argumento.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No contexto da programação orientada a objetos, o polimorfismo é alcançado por meio do conceito de &lt;strong&gt;herança&lt;/strong&gt; e da capacidade de uma classe base tratar objetos de suas subclasses de maneira &lt;strong&gt;uniforme&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Quando uma &lt;strong&gt;classe base&lt;/strong&gt; pode receber diferentes objetos de suas &lt;strong&gt;subclasses&lt;/strong&gt; e chamar métodos com o mesmo nome, mas com implementações específicas em cada subclasse, dizemos que a &lt;strong&gt;classe base é polimórfica&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Vamos adaptar o exemplo do animal para ilustrar esse conceito:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Classe base&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;makeSound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O animal faz um som.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Subclasse que estende a classe Animal&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;makeSound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O cachorro late.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Subclasse que estende a classe Animal&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Animal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;makeSound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O gato mia.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Função que recebe um objeto Animal e chama o método makeSound&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;makeAnimalSound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;makeSound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Criando instâncias das classes Dog e Cat&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Whiskers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Chamando a função makeAnimalSound com diferentes objetos&lt;/span&gt;
&lt;span class="nx"&gt;makeAnimalSound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: "O cachorro late."&lt;/span&gt;
&lt;span class="nx"&gt;makeAnimalSound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: "O gato mia."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, a classe &lt;code&gt;Animal&lt;/code&gt; é &lt;strong&gt;polimórfica&lt;/strong&gt;, pois pode receber diferentes objetos de suas subclasses &lt;code&gt;Dog&lt;/code&gt; e &lt;code&gt;Cat&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;makeAnimalSound&lt;/code&gt; recebe um objeto do tipo &lt;code&gt;Animal&lt;/code&gt; como argumento e chama o método &lt;code&gt;makeSound&lt;/code&gt; do objeto.&lt;/p&gt;

&lt;p&gt;Quando chamamos a função &lt;code&gt;makeAnimalSound&lt;/code&gt; passando um objeto &lt;code&gt;dog&lt;/code&gt;, o método &lt;code&gt;makeSound&lt;/code&gt; da classe &lt;code&gt;Dog&lt;/code&gt; é executado, produzindo o som específico do cachorro.&lt;/p&gt;

&lt;p&gt;Da mesma forma, quando passamos um objeto &lt;code&gt;cat&lt;/code&gt;, o método &lt;code&gt;makeSound&lt;/code&gt; da classe &lt;code&gt;Cat&lt;/code&gt; é executado, produzindo o som específico do gato.&lt;/p&gt;

&lt;p&gt;Dessa forma, a classe &lt;code&gt;Animal&lt;/code&gt; &lt;strong&gt;é polimórfica&lt;/strong&gt; porque pode tratar diferentes objetos de suas subclasses de maneira uniforme e executar o &lt;strong&gt;comportamento apropriado&lt;/strong&gt; para cada subclasse.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🙋🏻‍♀️ Eu: - Por favor, me dê um exemplo usando uma classe Product&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🤖 ChatGPT: - Claro! Aqui está um exemplo usando a classe Product (Produto) para ilustrar o polimorfismo:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Classe base&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;calculateDiscount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// sem desconto por padrão&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Subclasse que estende a classe Product&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SaleProduct&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;discountPercentage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;discountPercentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;discountPercentage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;calculateDiscount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;discountPercentage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Subclasse que estende a classe Product&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;ClearanceProduct&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clearancePrice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clearancePrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;clearancePrice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;calculateDiscount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clearancePrice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Função que recebe um objeto Product e calcula o desconto&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;calculateProductDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;discount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calculateDiscount&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`O desconto do produto &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; é de &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; reais.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Criando instâncias das classes SaleProduct e ClearanceProduct&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saleProduct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;SaleProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Camiseta&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 20% de desconto&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clearanceProduct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ClearanceProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Calça&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// preço de liquidação de 70 reais&lt;/span&gt;

&lt;span class="c1"&gt;// Chamando a função calculateProductDiscount com diferentes objetos&lt;/span&gt;
&lt;span class="nx"&gt;calculateProductDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;saleProduct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: "O desconto do produto Camiseta é de 10 reais."&lt;/span&gt;
&lt;span class="nx"&gt;calculateProductDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clearanceProduct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: "O desconto do produto Calça é de 30 reais."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse exemplo, temos uma &lt;strong&gt;classe base&lt;/strong&gt; chamada &lt;code&gt;Product&lt;/code&gt; com um método &lt;code&gt;calculateDiscount&lt;/code&gt;, que retorna o desconto do produto (ou zero, se não houver desconto).&lt;/p&gt;

&lt;p&gt;Em seguida, temos duas &lt;strong&gt;subclasses&lt;/strong&gt;, &lt;code&gt;SaleProduct&lt;/code&gt; (Produto em promoção) e &lt;code&gt;ClearanceProduct&lt;/code&gt; (Produto em liquidação), que estendem a classe base Product e &lt;strong&gt;substituem o método&lt;/strong&gt; &lt;code&gt;calculateDiscount&lt;/code&gt; para calcular o desconto de acordo com as regras específicas de cada subclasse.&lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;calculateProductDiscount&lt;/code&gt; recebe um objeto do tipo &lt;code&gt;Product&lt;/code&gt; (que pode ser uma instância de SaleProduct ou ClearanceProduct) e chama o método &lt;code&gt;calculateDiscount&lt;/code&gt; do objeto para obter o valor do desconto.&lt;/p&gt;

&lt;p&gt;Ao criar &lt;strong&gt;instâncias&lt;/strong&gt; das subclasses &lt;code&gt;SaleProduct&lt;/code&gt; e &lt;code&gt;ClearanceProduct&lt;/code&gt; e chamar a função &lt;code&gt;calculateProductDiscount&lt;/code&gt; com essas instâncias, obtemos resultados diferentes, dependendo do tipo do objeto.&lt;/p&gt;

&lt;p&gt;O método &lt;code&gt;calculateDiscount&lt;/code&gt; &lt;strong&gt;apropriado&lt;/strong&gt; é executado para cada subclasse, fornecendo o valor de desconto correto para cada produto.&lt;/p&gt;

&lt;p&gt;Dessa forma, o exemplo ilustra o polimorfismo na classe Product, onde diferentes objetos podem responder ao mesmo método de maneira diferente, permitindo um código mais &lt;strong&gt;flexível&lt;/strong&gt; e &lt;strong&gt;reutilizável&lt;/strong&gt;.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🙋🏻‍♀️ Eu: - Me dê o mesmo exemplo usando functions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🤖 ChatGPT: - Claro! Aqui está um exemplo usando funções em vez de classes para ilustrar o polimorfismo:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Função base&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;calculateDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// sem desconto por padrão&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Função para calcular o desconto de um produto em promoção&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;calculateSaleDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;discountPercentage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Função para calcular o desconto de um produto em liquidação&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;calculateClearanceDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clearancePrice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Objeto representando um produto em promoção&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saleProduct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Camiseta&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;discountPercentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 20% de desconto&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Objeto representando um produto em liquidação&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clearanceProduct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Calça&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;clearancePrice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// preço de liquidação de 70 reais&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Função que recebe um objeto produto e uma função de desconto e calcula o desconto&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;calculateProductDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;discountFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;discount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;discountFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`O desconto do produto &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; é de &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; reais.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Chamando a função calculateProductDiscount com diferentes objetos e funções de desconto&lt;/span&gt;
&lt;span class="nx"&gt;calculateProductDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;saleProduct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;calculateSaleDiscount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: "O desconto do produto Camiseta é de 10 reais."&lt;/span&gt;
&lt;span class="nx"&gt;calculateProductDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clearanceProduct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;calculateClearanceDiscount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Saída: "O desconto do produto Calça é de 30 reais."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesse exemplo, temos funções separadas para calcular o desconto de diferentes tipos de produtos. A função &lt;code&gt;calculateDiscount&lt;/code&gt; é a função base que retorna o desconto padrão de zero.&lt;/p&gt;

&lt;p&gt;As funções &lt;code&gt;calculateSaleDiscount&lt;/code&gt; e &lt;code&gt;calculateClearanceDiscount&lt;/code&gt; são exemplos de funções específicas para calcular descontos de produtos em promoção e em liquidação, respectivamente.&lt;/p&gt;

&lt;p&gt;Em vez de usar classes, utilizamos &lt;strong&gt;objetos&lt;/strong&gt; para representar os produtos em promoção e em liquidação.&lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;calculateProductDiscount&lt;/code&gt; recebe um &lt;code&gt;objeto de produto&lt;/code&gt; e uma &lt;code&gt;função de desconto&lt;/code&gt; &lt;strong&gt;como argumentos&lt;/strong&gt;. Ela chama a &lt;code&gt;função de desconto&lt;/code&gt; passando o objeto de produto e retorna o valor do desconto.&lt;/p&gt;

&lt;p&gt;Ao chamar a função &lt;code&gt;calculateProductDiscount&lt;/code&gt; com diferentes objetos de produto e funções de desconto correspondentes, obtemos resultados diferentes, cada um correspondendo ao desconto específico do tipo de produto.&lt;/p&gt;

&lt;p&gt;Dessa forma, conseguimos obter um &lt;strong&gt;comportamento polimórfico&lt;/strong&gt; ao passar diferentes objetos de produto e funções de desconto para a função &lt;code&gt;calculateProductDiscount&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Cada função de desconto é executada para o tipo de produto apropriado, fornecendo o valor de desconto correto.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🙋🏻‍♀️ Eu: - Polimorfismo de uma function tem a ver com abstração de código?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🤖 ChatGPT: - Sim, o polimorfismo em funções está relacionado à abstração de código. O polimorfismo permite tratar diferentes objetos ou tipos de dados de maneira uniforme, ocultando detalhes específicos de implementação e fornecendo uma &lt;strong&gt;interface abstrata&lt;/strong&gt; para interagir com eles.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ao utilizar o polimorfismo, podemos escrever &lt;strong&gt;código genérico&lt;/strong&gt; que pode lidar com diferentes tipos de dados ou objetos, sem se preocupar com os detalhes específicos de cada um. Isso leva a um código mais &lt;strong&gt;flexível&lt;/strong&gt;, &lt;strong&gt;modular&lt;/strong&gt; e &lt;strong&gt;reutilizável&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Quando aplicamos o polimorfismo em funções, podemos passar diferentes objetos ou tipos de dados como argumentos para a mesma função, permitindo que a função opere de maneira polimórfica em cada um deles. A função pode tratar esses objetos ou tipos de dados de forma abstrata, chamando métodos comuns ou aplicando operações genéricas a eles.&lt;/p&gt;

&lt;p&gt;Essa abstração de código oferecida pelo polimorfismo permite que você escreva funções genéricas que podem ser reutilizadas com diferentes objetos ou tipos de dados, promovendo uma melhor modularidade, flexibilidade e capacidade de extensão do código.&lt;/p&gt;

&lt;p&gt;Portanto, o polimorfismo em funções desempenha um papel importante na abstração de código, permitindo que você escreva código mais genérico, modular e flexível, ao tratar diferentes objetos ou tipos de dados de forma uniforme.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🙋🏻‍♀️ Eu: - Por exemplo, em uma aplicação em React, recebemos produtos da api e precisamos converter seu preço (number) para o valor da moeda do país selecionado. Posso considerar essa function localeCurrency como uma function polimórfica?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🤖 ChatGPT: - Sim, você pode considerar a função &lt;code&gt;localeCurrency&lt;/code&gt; nesse cenário como uma função polimórfica. O polimorfismo ocorre quando uma função pode operar em diferentes tipos de dados ou objetos de maneira uniforme.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No seu exemplo em uma aplicação React, a função &lt;code&gt;localeCurrency&lt;/code&gt; recebe um número (preço) e converte esse valor para a moeda específica com base no país selecionado.&lt;/p&gt;

&lt;p&gt;Essa função pode ser aplicada a diferentes produtos e realizar a conversão da moeda corretamente, independentemente do tipo de produto ou do valor do preço.&lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;localeCurrency&lt;/code&gt; é &lt;strong&gt;polimórfica&lt;/strong&gt; porque ela pode ser usada com diferentes números (preços) e &lt;strong&gt;fornecer a conversão adequada para cada um deles, independentemente do tipo específico do produto.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ao utilizar a função &lt;code&gt;localeCurrency&lt;/code&gt; em diferentes contextos, você está tratando diferentes objetos (produtos) de maneira uniforme, aplicando a mesma lógica de conversão de moeda a cada um deles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Essa capacidade de tratar diferentes objetos de forma genérica e aplicar operações consistentes é uma característica fundamental do polimorfismo.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Portanto, nesse caso, a função localeCurrency pode ser considerada uma função polimórfica, pois opera em diferentes valores numéricos (preços) de maneira uniforme, fornecendo a conversão correta da moeda com base na língua selecionada.&lt;/p&gt;




</description>
    </item>
    <item>
      <title>[pt-BR] Problemas com pacotes do npm? Verdaccio pode ser a solução</title>
      <dc:creator>Adriana Ferreira Lima Shikasho</dc:creator>
      <pubDate>Wed, 04 May 2022 20:10:01 +0000</pubDate>
      <link>https://dev.to/dxwebster/pt-br-problemas-com-pacotes-do-npm-verdaccio-pode-ser-a-solucao-2966</link>
      <guid>https://dev.to/dxwebster/pt-br-problemas-com-pacotes-do-npm-verdaccio-pode-ser-a-solucao-2966</guid>
      <description>&lt;p&gt;Este é um conteúdo adaptado do vídeo &lt;a href="https://www.youtube.com/watch?v=hDIFKzmoCaA"&gt;Vienna.js, Introduction to Verdaccio, January 2019&lt;/a&gt;. Para mais informações, veja &lt;a href="https://verdaccio.org/docs/what-is-verdaccio"&gt;What is Verdaccio? | Verdaccio&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Verdaccio é um &lt;strong&gt;registro de proxy npm&lt;/strong&gt; privado e leve para pacotes NodeJs. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A configuração é muito fácil e é feita local por meio de um arquivo config.yaml, e permite modificar o comportamento padrão, ativar plugins e recursos externos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;É compatível com todos os gerenciadores de pacotes como npm, yarn ou pnpm.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Todos os pacotes que você publica são privados e acessíveis apenas com base em sua configuração.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Armazena em cache todas as dependências sob demanda e agiliza as instalações em redes locais ou privadas.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  NPM Registry
&lt;/h1&gt;

&lt;p&gt;O NPM Registry é uma coleção open source de pacotes NodeJS com registros públicos, usado por back-end e front-end developers. Esses pacotes podem ser baixados e instalados por meio dos gerenciadores de pacotes como: npm (npm Inc), yarn (Facebook, Google, Exponent, Tidle), pnpm (Zoltan Kochan). Não importa qual gerenciador utilizarmos para instalar os pacotes de Node, eles farão a mesma coisa: requisições para o NPM Registry.&lt;/p&gt;

&lt;p&gt;Quando instalamos um pacote, esperamos receber apenas um pacote, certo? Mas a verdade é que quando instalamos um pacote, recebemos muito mais pacotes do que esperávamos.&lt;/p&gt;

&lt;p&gt;No contexto de javascript, a quantidade de pacotes publicados passa de 100k e está crescendo a cada dia. &lt;a href="https://www.linkedin.com/in/coryhouse/"&gt;Cory House&lt;/a&gt;, especialista em React e JavaScript, publicou em seu Twitter a seguinte afirmação: "[...] atualmente, 97% do código de aplicações web vem do npm. Apenas 3% do código foi você que escreveu.” &lt;/p&gt;

&lt;p&gt;Ou seja, nós dependemos completamente do NPM registry e devemos levar isso a sério pois esse registro pode falhar - &lt;a href="https://blog.npmjs.org/post/169582189317/incident-report-npm-inc-operations-incident-of.html"&gt;como já aconteceu em agosto de 2018&lt;/a&gt;, quando acidentalmente um funcionário da npm Inc apagou alguns pacotes.&lt;/p&gt;

&lt;p&gt;Podemos listar outros problemas que podem acontecer ao depender do npm como: Latência e problemas de conexão, preço e segurança estão foras do nosso controle, e o desenvolvimento offline que possui diversas limitações. &lt;/p&gt;

&lt;h3&gt;
  
  
  Offline
&lt;/h3&gt;

&lt;p&gt;O npm cria um cache mas não permite compartilhá-lo (a não ser que você crie um registro de proxy); não permite a utilização de alguns comandos CLI como publish e info; áreas de funcionamento isoladas por políticas de seguranças restritas em algumas empresas, sendo necessário contatar time de operaçoes para permissões.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conexão
&lt;/h3&gt;

&lt;p&gt;Internet com conexão lenta prejudicam a velocidade de download. Alguns pacotes podem ser corrompidos por bloqueios de firewall (China por exemplo), ou os planos de internet são bem limitados (Russia, pode cobrar 60 euros para enviar apenas 1 email).&lt;/p&gt;

&lt;h3&gt;
  
  
  Segurança
&lt;/h3&gt;

&lt;p&gt;Confiar seu código a empresas terceiras; dados confidenciais podem ser vazados ao npm.&lt;/p&gt;

&lt;h1&gt;
  
  
  A solução do Verdaccio
&lt;/h1&gt;

&lt;p&gt;Ter registros é essencial para escalar projetos novos, mas fontes privadas são privilégios caros para pequenos grupos ou start-ups. Verdaccio vem como uma solução acessível para todos os problemas que vimos até agora.&lt;/p&gt;

&lt;p&gt;Sua instalação é muito fácil, basta instalar globalmente executando: &lt;code&gt;npm install —global verdaccio@latest&lt;/code&gt; , e rodar sua CLI com o comando &lt;code&gt;verdaccio&lt;/code&gt;. É possível utiliza-lo também com o docker. Alguns recursos do Verdaccio:&lt;/p&gt;

&lt;h3&gt;
  
  
  Registro Privado
&lt;/h3&gt;

&lt;p&gt;Podemos desfrutar de todos os benefícios e controle do registro npm sem tornar o nosso código público, pois tudo é feito localmente. Além disso, se você quiser usar uma versão modificada de algum pacote de terceiros, poderá publicar sua versão localmente com o mesmo nome.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proxy / Uplinks
&lt;/h3&gt;

&lt;p&gt;As ferramentas do cliente só trabalham com um registro por vez, mas podemos associar todos os registros com um &lt;a href="https://docs.npmjs.com/cli/v8/using-npm/scope"&gt;recurso de escopo&lt;/a&gt; do npm (~/.npmrc), como o exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;registry=https://registry.npmjs.org&lt;/span&gt;
&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="s"&gt;mycompany:registry=http://verdaccio-domain:4873&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Entretanto, dessa forma é difícil de manter e de certa forma insegura, porque uma vez que isso é publicado acidentalmente ao github, tokens podem ser compartilhados ao publico.&lt;/p&gt;

&lt;p&gt;O Verdaccio é um aplicativo de &lt;strong&gt;servidor proxy npm&lt;/strong&gt; que atua como intermediário entre o cliente e solicita um recurso ao servidor npm.&lt;/p&gt;

&lt;p&gt;Se você usa vários registros em sua organização e precisa buscar pacotes de várias fontes em um único projeto, o Verddacio permite encadear vários registros e buscar em um único endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://verdaccio.org/docs/uplinks/"&gt;Uplinks&lt;/a&gt;&lt;/strong&gt; é o recurso que o Verddacio tem para associar multiplos registros. Um pacote pode ser fetch por multiplos registros como fallback, se um falhar, você terá outro disponível. &lt;/p&gt;

&lt;h3&gt;
  
  
  Cache de pacotes
&lt;/h3&gt;

&lt;p&gt;Cache consiste num monte de dependências organizadas por nome. Uma dependência, consiste num arquivo metadata com um monte de &lt;em&gt;tarballs&lt;/em&gt;, que é a versão binária do pacote. O cache irá te cobrir quando a conexão com o registro falhar ou quando você tiver totalmente offline.&lt;/p&gt;

&lt;p&gt;O armazenamento do verdaccio é sistema baseado em arquivos, mas você pode usar algo diferente se você deseja escalar, como por exemplo usar Amazon s3 bucket para utilizar o verdaccio em nuvem.&lt;/p&gt;

&lt;p&gt;O caching é importante principalmente para Integração Contínua (CI), pois você quer evitar falhas por questões externas. Com cache podemos salvar largura de banda e reduzir tráfico externo, principalmente quando rodamos o CI na nuvem, pois cada megabyte custa dinheiro.&lt;/p&gt;

&lt;p&gt;O verdaccio é super recomendado a ser utilizado entre o servidor de build e o registro externo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Possui plugins
&lt;/h3&gt;

&lt;p&gt;Pode-se utilizar plugins gratuitos com o verdaccio, como plugins de autenticação (gitlab, LDAP), plugins de armazenamento (AWS, GCP), e por ser uma aplicação express nodejs, você pode adicionar seus endpoints ou pode interceptar suas requisições com plugins de middleware (npm audit).&lt;/p&gt;

&lt;h3&gt;
  
  
  Interface de usuário na web
&lt;/h3&gt;

&lt;p&gt;Podemos pesquisar e navegar por pacotes privados e verificar todos os metadados que o pacote oferece: regulamento, autor, últimas versões, dependências, etc&lt;/p&gt;

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

&lt;p&gt;Se você usa monorepo, é recomendado testar todos os pacotes antes de publicá-los.&lt;/p&gt;




&lt;h1&gt;
  
  
  Como instalar e configurar o verdaccio
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Instale verdaccio globalmente:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;yarn global add verdaccio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rode &lt;code&gt;verdaccio&lt;/code&gt; para criar o arquivo de configuração default &lt;code&gt;config.yaml&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;verdaccio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Abra o config.yaml no VSCode:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;code ~/.config/verdaccio/config.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Adicione o github no &lt;code&gt;uplinks&lt;/code&gt;, e inclua seu &lt;a href="https://docs.github.com/pt/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token"&gt;token de acesso pessoal&lt;/a&gt; no auth.token:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;uplinks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;npmjs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://registry.npmjs.org/&lt;/span&gt;
  &lt;span class="na"&gt;github&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://npm.pkg.github.com/&lt;/span&gt;
    &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bearer&lt;/span&gt;
      &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;GITHUB_PERSONAL_TOKEN&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Adicione os pacotes que deseja rodar localmente nos packages&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;packages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;@belezanaweb/*'&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$all&lt;/span&gt;
    &lt;span class="na"&gt;publish&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$authenticated&lt;/span&gt;
    &lt;span class="na"&gt;unpublish&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$authenticated&lt;/span&gt;
    &lt;span class="na"&gt;proxy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🙌🏼  &lt;strong&gt;Pronto! O verdaccio está configurado para ser utilizado!&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[pt-BR] Terraform: Provisionamento de Nuvem com IaC - #3</title>
      <dc:creator>Adriana Ferreira Lima Shikasho</dc:creator>
      <pubDate>Wed, 06 Apr 2022 15:39:01 +0000</pubDate>
      <link>https://dev.to/dxwebster/pt-br-provisionamento-de-nuvem-com-iac-3-32h9</link>
      <guid>https://dev.to/dxwebster/pt-br-provisionamento-de-nuvem-com-iac-3-32h9</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V_TMYDoZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.vectorlogo.zone/logos/terraformio/terraformio-ar21.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V_TMYDoZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.vectorlogo.zone/logos/terraformio/terraformio-ar21.svg" alt="Terraform-logo" width="120" height="60"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Conhecendo o Terraform&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Infrastructure as Code (IaC)&lt;/li&gt;
&lt;li&gt;Configuração do Ambiente de Desenvolvimento&lt;/li&gt;
&lt;li&gt;Comandos básicos do Terraform&lt;/li&gt;
&lt;li&gt;Criação de Máquina Virtual + Apache Server (Iaas)&lt;/li&gt;
&lt;li&gt;Variáveis no Terraform&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Infrastructure as Code (IaC)
&lt;/h1&gt;

&lt;p&gt;Em ambientes on-premises, a infraestrutura tem recursos físicos de hardware como servidores, máquinas, locação refrigerada e recursos humanos para instalar e configurar sistemas operacionais, ferramentas de desenvolvimento e fazer a manutenção das operações.&lt;/p&gt;

&lt;p&gt;Em ambientes em nuvem, toda infraestrutura é virtualizada, ou seja, ainda existe um ambiente físico, mas sob total responsabilidade dos provedores de nuvem. O usuário consegue criar máquinas e servidores e conectar cabos por exemplo, tudo de maneira virtual, por meio de interface ou por meio de código.&lt;/p&gt;

&lt;p&gt;Pela interface, é necessário entrar na conta do provedor para criar e gerenciar seus recursos, como por exemplo na plataforma da &lt;a href="https://azure.microsoft.com/pt-br/"&gt;Azure&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Por código, pode-se utilizar orquestradores de nuvem, como por exemplo o &lt;a href="https://registry.terraform.io/"&gt;Terraform&lt;/a&gt;, que permite gerenciar os recursos por meio da escrita de scripts em um formato parecido com JSON ou YML. Essa forma de fazer infraestrutura é o que se chama de &lt;strong&gt;Infrastructure as Code (IaC)&lt;/strong&gt;, ou seja, gerenciar infraestrutura por meio de código.&lt;/p&gt;

&lt;h1&gt;
  
  
  Configuração do Ambiente de Desenvolvimento
&lt;/h1&gt;

&lt;p&gt;Para fazer IaC, precisamos configurar o ambiente de desenvolvimento. Escolhemos a Azure como provedor de nuvem e o Terraform como gerenciador de Nuvem. O ambiente de desenvolvimento é bem simples e requer apenas 3 passos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Criar conta na &lt;a href="https://azure.microsoft.com/pt-br/"&gt;Azure&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Instalar &lt;a href="https://docs.microsoft.com/pt-br/cli/azure/"&gt;AZ CLI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Instalar &lt;a href="https://www.terraform.io/downloads"&gt;Terraform&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Obs: Existem ferramentas que também nos auxiliam na criação do ambiente para desenvolvimento de nuvem, como o &lt;a href="https://www.vagrantup.com/downloads"&gt;Vagrant&lt;/a&gt;, mas aqui vamos começar de forma mais simples apenas para conhecer o Azure e o Terraform. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Comandos básicos do Terraform
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Criar uma pasta para o projeto e executar &lt;code&gt;terraform init&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Criar um arquivo main.tf para escrever o script com toda a descrição de infra&lt;/li&gt;
&lt;li&gt;Executar &lt;code&gt;terraform validate&lt;/code&gt;para verificar se a sintaxe do script está correta&lt;/li&gt;
&lt;li&gt;Executar &lt;code&gt;terraform plan&lt;/code&gt; para rever o que será executado no script (diff)&lt;/li&gt;
&lt;li&gt;Executar &lt;code&gt;terraform apply&lt;/code&gt;para subir e rodar o script na nuvem&lt;/li&gt;
&lt;li&gt;Para excluir tudo da nuvem, executar &lt;code&gt;terraform destroy&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Criação de Máquina Virtual + servidor Apache na Azure
&lt;/h1&gt;

&lt;p&gt;Na Azure, os hadwares, softwares e ferramentas disponíveis para infraestrutura são chamados de &lt;strong&gt;Recursos&lt;/strong&gt;.&lt;br&gt;
Para criar uma máquina virtual + Apache server, é necessário criar um &lt;strong&gt;Resource Group&lt;/strong&gt; que vai agrupar os seguintes recursos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Recursos relacionados à rede:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Virtual Network&lt;/li&gt;
&lt;li&gt;IP Público&lt;/li&gt;
&lt;li&gt;Firewall&lt;/li&gt;
&lt;li&gt;Placa de Rede&lt;/li&gt;
&lt;li&gt;Sub-Rede&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Recursos relacionados à Máquina Virtual&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conta de Armazenamento&lt;/li&gt;
&lt;li&gt;Máquina Virtual&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Recursos relacionadas a Deploy&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Executor de script&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em todos os provedores de nuvem, os recursos são os mesmos, mas podem ter nomes e características diferentes. Vamos conhecer os recursos da Azure necessários para criar uma máquina virtual com servidor Apache.&lt;/p&gt;
&lt;h2&gt;
  
  
  Resource Group
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group"&gt;&lt;em&gt;azurerm_resource_group&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O Resource Group (Grupo de Recursos) tem como finalidade agrupar os recursos do Azure com um objetivo específico.&lt;br&gt;
Esse agrupamento permite o administrador realizar a criação, monitoramento, controle de acessos e de custo de cada grupo de recursos.&lt;/p&gt;
&lt;h2&gt;
  
  
  Virtual Network (vnet)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network"&gt;&lt;em&gt;azurerm_virtual_network&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A rede virtual permite a comunicação entre várias máquinas virtuais em diferentes locais pela internet por meio de softwares (diferente da rede física que utiliza cabeamento e hardwares). Esses softwares são versões virtualizadas de ferramentas de rede tradicionais, como switches e adaptadores de rede, permitindo roteamento mais eficiente e alterações de configuração de rede mais fáceis.&lt;/p&gt;
&lt;h2&gt;
  
  
  SubNet
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet"&gt;&lt;em&gt;azurerm_subnet&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As sub-redes representam segmentos de rede dentro do espaço IP definido pela rede virtual. A subdivisão de uma rede grande em redes menores resulta num tráfego de rede reduzido, administração simplificada e melhor performance de rede&lt;/p&gt;
&lt;h2&gt;
  
  
  Public IP
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip"&gt;&lt;em&gt;azurerm_public_ip&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Um endereço público significa que ele pode ser acessado pela Internet. Em redes compartilhadas, os dispositivos conectados podem ter endereços IP privados próprios, mas quando se conectam pela conexão de Internet, são convertidos em um endereço IP público atribuído ao roteador.&lt;/p&gt;
&lt;h2&gt;
  
  
  Network Security Group (NSG)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_security_group"&gt;&lt;em&gt;azurerm_network_security_group&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basicamente uma NSG é um Firewall (lógico) de rede, sua função é filtrar todo o tráfego direcionado a um recurso por meio de regras de segurança, e tomar as devidas ações. Controla a permissão de tráfego de rede de entrada ou de saída em relação a vários tipos de recursos do Azure. Para cada regra, você pode especificar origem e destino, porta e protocolo.&lt;/p&gt;
&lt;h2&gt;
  
  
  Network Interface (NIC)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface"&gt;&lt;em&gt;azurerm_network_interface&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A placa de interface de rede (NIC) é atribuída com o endereço IP e associada às regras NSG, que são usadas para a comunicação entre a máquina virtual ou a rede interna ou a Internet.&lt;/p&gt;
&lt;h2&gt;
  
  
  Network Interface Security Group Association (NIC-NSG)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface_security_group_association"&gt;&lt;em&gt;azurerm_network_interface_security_group_association&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Um recurso apenas para conectar um Network Security Group (NSG) a uma interface de rede (NIC).&lt;/p&gt;
&lt;h2&gt;
  
  
  Storage Account (SA)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account"&gt;&lt;em&gt;azurerm_storage_account&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uma conta de armazenamento do Azure contém todos os seus objetos de dados do Armazenamento do Azure, incluindo blobs, compartilhamentos de arquivos, filas, tabelas e discos. A conta de armazenamento fornece um namespace exclusivo para seus dados de armazenamento do Azure que podem ser acessados de qualquer lugar do mundo por HTTP ou HTTPS.&lt;/p&gt;
&lt;h2&gt;
  
  
  Virtual Machine (VM)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine"&gt;&lt;em&gt;azurerm_virtual_machine&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As Máquinas Virtuais do Azure (VM) são um dos vários tipos de recursos de computação escalonáveis sob demanda que o Azure oferece. Normalmente, você escolhe uma VM quando precisa de mais controle sobre o ambiente de computação do que as outras opções oferecem.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Para verificar o tamanho das máquinas disponíveis na Azure, &lt;a href="https://docs.microsoft.com/pt-br/azure/virtual-machines/sizes"&gt;ver aqui&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  null_resource
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource"&gt;null_resource&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O null_resource é um recurso que permite configurar 3 provisionadores que não estão diretamente associados a um recurso existente. Se comporta exatamente como qualquer outro recurso, portanto, você configura provisionadores, detalhes de conexão e outros metaparâmetros da mesma maneira que faria em qualquer outro recurso.&lt;/p&gt;

&lt;p&gt;Os 3 tipos de provisionadores (provisioner) são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;file&lt;/strong&gt;: faz upload de arquivo/pasta (com aplicação) para a VM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;remote-exec&lt;/strong&gt;: executa um script na VM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;local-exec&lt;/strong&gt;: executa um script na minha máquina local&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com remote-exec pode-se executar scripts na VM, ou seja, podemos instalar o apache ou qualquer outra coisa na máquina. Abaixo é a configuração de instalação do servidor Apache&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;resource "null_resource" "install-apache" {&lt;/span&gt;
  &lt;span class="s"&gt;connection {&lt;/span&gt;
    &lt;span class="s"&gt;type     = "ssh"&lt;/span&gt;
    &lt;span class="s"&gt;host     = data.azurerm_public_ip.var_publicip.ip_address&lt;/span&gt;
    &lt;span class="s"&gt;user     = var.user&lt;/span&gt;
    &lt;span class="s"&gt;password = var.password&lt;/span&gt;
  &lt;span class="s"&gt;}&lt;/span&gt;
  &lt;span class="s"&gt;# remote-exec executa um script na VM&lt;/span&gt;
  &lt;span class="s"&gt;provisioner "remote-exec" {&lt;/span&gt;
    &lt;span class="s"&gt;inline = [&lt;/span&gt;
      &lt;span class="s"&gt;"sudo apt update",&lt;/span&gt;
      &lt;span class="s"&gt;"sudo apt install -y apache2",&lt;/span&gt;
    &lt;span class="s"&gt;]&lt;/span&gt;
  &lt;span class="s"&gt;}&lt;/span&gt;
  &lt;span class="s"&gt;# Indica que esse &lt;/span&gt;&lt;span class="no"&gt;null&lt;/span&gt;&lt;span class="s"&gt;_resource depende da criação da VM&lt;/span&gt;
  &lt;span class="s"&gt;depends_on = [azurerm_virtual_machine.atividade-infra-vm]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Obs: Para usar o null_resource, precisa rodar o &lt;code&gt;terraform init&lt;/code&gt; novamente, para baixar este plugin.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Variáveis no Terraform
&lt;/h1&gt;

&lt;p&gt;Existem várias formas de informar os valores das variáveis que usamos no script do Terraform:&lt;/p&gt;

&lt;h2&gt;
  
  
  Na execução do terraform
&lt;/h2&gt;

&lt;p&gt;No momento de execução do &lt;code&gt;terraform plan&lt;/code&gt;o terminal vai solicitar a inclusão dos valores das variáveis que foram declaradas&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquivo de variáveis
&lt;/h2&gt;

&lt;p&gt;Criar um arquivo "terraform.tfvars" não-versionado na raíz do projeto com a declaraçao das variáveis e seus valores&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// terraform.tfvars&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Password123456!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Variável Ambiente Local
&lt;/h2&gt;

&lt;p&gt;Criar variável ambiente na máquina local (Linux):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TF_VAR_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"admin"&lt;/span&gt;
  &lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TF_VAR_PWD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Password123456!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para verificar a variável criada, executar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$TF_VAR_USER&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Gerenciador de Senhas
&lt;/h2&gt;

&lt;p&gt;O gerenciador de senhas protege, armazena e controla rigidamente o acesso a tokens, senhas, certificados, chaves de criptografia para proteger segredos e outros dados confidenciais usando uma interface do usuário, CLI ou API HTTP.&lt;/p&gt;

&lt;p&gt;Exemplos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.vaultproject.io/downloads"&gt;Vault&lt;/a&gt; da Hashcorp&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://azure.microsoft.com/en-ca/services/key-vault/"&gt;Key Vault&lt;/a&gt; da Azure&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>[pt-BR] Migração e Implementação de Cloud - #2</title>
      <dc:creator>Adriana Ferreira Lima Shikasho</dc:creator>
      <pubDate>Fri, 25 Mar 2022 22:54:20 +0000</pubDate>
      <link>https://dev.to/dxwebster/pt-br-infraestrutura-e-computacao-em-nuvem-parte-2-4bnb</link>
      <guid>https://dev.to/dxwebster/pt-br-infraestrutura-e-computacao-em-nuvem-parte-2-4bnb</guid>
      <description>&lt;p&gt;Agora que já conhecemos a &lt;em&gt;cultura devOps&lt;/em&gt;, as vantagens da &lt;em&gt;computação em nuvem&lt;/em&gt; em relação ao ambiente on-premise e vimos um pouco dos &lt;em&gt;modelos de serviços em nuvem&lt;/em&gt; - Iaas, Saas e Paas - vamos aprender mais 3 tópicos referentes a cloud:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Migração para serviços de Cloud:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Re-host&lt;/li&gt;
&lt;li&gt;Re-platform&lt;/li&gt;
&lt;li&gt;Re-factor&lt;/li&gt;
&lt;li&gt;Re-purchase&lt;/li&gt;
&lt;li&gt;Retire&lt;/li&gt;
&lt;li&gt;Retain&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modelos de Implantação de Cloud:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nuvem Pública&lt;/li&gt;
&lt;li&gt;Nuvem Privada&lt;/li&gt;
&lt;li&gt;Nuvem Híbrida&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ambientes Single-Cloud X Multi-Cloud&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;blockquote&gt;
&lt;p&gt;Esse conteúdo foi baseado na Aula 1 de Infraestructure e Cloud Computing da &lt;a href="https://www.impacta.edu.br/mba/full-stack-developer"&gt;pós-graduação de MBA em Desenvolvimento FullStack da Impacta&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  1. Migração para serviços de Cloud
&lt;/h1&gt;

&lt;p&gt;Vamos usar como exemplo a Amazon que com a AWS se tornou o primeiro player de nuvem do mercado. A AWS presta consultoria para que clientes migrem seus sistemas para a nuvem oferecendo 6 tipos de migração, também chamados de Jornada de Cloud:&lt;/p&gt;

&lt;h2&gt;
  
  
  Re-host
&lt;/h2&gt;

&lt;p&gt;Ambiente Iaas. É a porta de entrada para o ambiente em nuvem, tecnicamente a migração mais simples pois do jeito que está no ambiente on-premise vai pra nuvem.&lt;/p&gt;

&lt;p&gt;Por exemplo, as mesmas 5 máquinas virtuais vao ser colocadas no ambiente em nuvem, testadas, ver se tudo está funcionando e pronto. Não se aproveita todo o desempenho da nuvem pois foi feita uma migração bem básica.&lt;/p&gt;

&lt;p&gt;As aplicações que rodam no ambiente que sofreram re-host são classificadas como &lt;strong&gt;Cloud Enabled&lt;/strong&gt;, pois não foram feitas para rodar em nuvem, mas foram portadas para um ambiente em nuvem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Re-platform
&lt;/h2&gt;

&lt;p&gt;Ambiente Iaas + Paas. É o segundo step caso a empresa esteja interessada em trazer mais recursos para a nuvem. Ou seja, além das máquinas virtuais estarem na AWS, agora a empresa contrata algumas ferramentas para processamento, rede, desenvolvimento, banco de dados, etc e outros serviços.&lt;/p&gt;

&lt;p&gt;As aplicações que sofreram re-platform são classificadas como &lt;strong&gt;Cloud Based&lt;/strong&gt;, pois houveram modificações no sistema feito fora da nuvem, para rodar em nuvem. &lt;/p&gt;

&lt;h2&gt;
  
  
  Re-factor
&lt;/h2&gt;

&lt;p&gt;Ambiente Iaas + Paas + Saas. Quando não vale a pena migrar um ou mais sistemas já existentes da empresa, então são feitos novos sistemas já seguindo o modelo em nuvem (Microserviços, Conteinerização, Serveless). É a migração mais complexa e permite o uso e nuvem em sua total capacidade.&lt;/p&gt;

&lt;p&gt;As aplicações que sofreram re-factor são classificadas como &lt;strong&gt;Cloud Native&lt;/strong&gt; pois foram feitas para o ambiente em nuvem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Re-purchase
&lt;/h2&gt;

&lt;p&gt;Quando não vale a pena migrar os sistemas já existentes na empresa, e também não serão desenvolvidos novos sistemas, então a empresa compra sistemas Saas por exemplo do provedor de nuvem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retire
&lt;/h2&gt;

&lt;p&gt;Quando determinado sistema não vai migrar para nuvem e não será mais utilizado, é a aposentadoria do sistema, ele não é mais útil para a empresa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retain
&lt;/h2&gt;

&lt;p&gt;Quando determinado sistema não vai ser migrado para a nuvem, e fica no ambiente on-premise.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Modelos de Implantação de Nuvem
&lt;/h1&gt;

&lt;p&gt;Quando uma empresa planeja sua estratégia de cloud, ela pode optar por 3 modelos de implantação, sendo Nuvem Pública, Nuvem Privada e Nuvem Híbrida.&lt;/p&gt;

&lt;p&gt;Como sempre, cada modelo tem vantagens e desvantagens, e a escolha depende muito da estratégia da empresa. Vamos ver um pouco de cada um desses modelos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nuvem Pública
&lt;/h2&gt;

&lt;p&gt;Atualmente, o modelo de nuvem pública é a maneira mais comum de implantar a computação em nuvem, sendo o mais utilizado por empresas do mundo todo.&lt;/p&gt;

&lt;p&gt;O provedor tem servidores próprios para alocar dados, softwares e sistemas de forma independente e isolada.&lt;/p&gt;

&lt;p&gt;A Nuvem pública é basicamente uma nuvem aberta para qualquer pessoa ou empresa. AWS, GCP, Azure são alguns exemplos de provedores de nuvem pública.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nuvem Privada
&lt;/h2&gt;

&lt;p&gt;É basicamente um ambiente em nuvem oferecido por algum provedor, mas sua instalação é feita dentro do servidor on-premise da empresa.&lt;/p&gt;

&lt;p&gt;Cada empresa pode personalizar seus recursos de modo a atender suas necessidades específicas, utilizando seus próprios hardwares.&lt;/p&gt;

&lt;p&gt;As nuvens privadas geralmente são usadas por órgãos governamentais, instituições financeiras e outras organizações de grande porte com operações críticas para os negócios, que buscam melhorar o controle sobre seu ambiente.&lt;/p&gt;

&lt;p&gt;Entretanto, esse é um serviço que aos poucos está sendo descontinuado por acabar trazendo mais problemas do que benefícios. Por exemplo, a elasticidade e região da nuvem privada pode ser limitada ao tamanho e localização única do data center da empresa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nuvem Híbrida
&lt;/h2&gt;

&lt;p&gt;A nuvem híbrida mescla os outros dois modelos, tendo características tanto da nuvem pública quanto da privada. Isso permite que as empresas aproveitem as vantagens das duas opções ao mesmo tempo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Para saber mais detalhes sobre os modelos de implantação, o site da Azure tem um bom resumo. Veja &lt;a href="https://azure.microsoft.com/pt-br/overview/what-are-private-public-hybrid-clouds/#overview"&gt;aqui&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  3. Ambientes Single-Cloud X Multi-Cloud
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2P7Yzenu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sl99g5o298jkxreskd0k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2P7Yzenu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sl99g5o298jkxreskd0k.png" alt="Image description" width="615" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Um ambiente único de Cloud (Single-Cloud) se caracteriza pela utilização de um único provedor para todos os serviços e aplicações da sua organização.&lt;/p&gt;

&lt;p&gt;Em contrapartida, um ambiente Multicloud é aquele em que a empresa usa os serviços de vários provedores de nuvem.&lt;/p&gt;

&lt;p&gt;O Multicloud é o mais indicado para evitar o "vendor lock-in" (aprisionamento tecnológico), que é uma forma do provedor manter o cliente "aprisionado"  e dependente de determinada particularidade em produtos, e os impede de trocar de fornecedor sem custos adicionais substanciais.&lt;/p&gt;

&lt;h2&gt;
  
  
  Boas práticas para evitar o Vendor Lock-in
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tecnologias open-source&lt;/li&gt;
&lt;li&gt;Conteinerização&lt;/li&gt;
&lt;li&gt;Portabilidade e interoperabilidade&lt;/li&gt;
&lt;li&gt;Infraestrutura como código&lt;/li&gt;
&lt;li&gt;Plano estratégico para migração&lt;/li&gt;
&lt;li&gt;Ambiente multicloud&lt;/li&gt;
&lt;li&gt;Treinamento interno&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Continua na parte 3 👉🏼 &lt;a href="https://dev.to/dxwebster/pt-br-provisionamento-de-nuvem-com-iac-3-32h9"&gt;clique aqui&lt;/a&gt; &lt;/p&gt;




&lt;p&gt;Referências:&lt;br&gt;
&lt;a href="https://www.softwareone.com/pt-br/blog/artigos/2020/01/22/multicloud-softwareone"&gt;https://www.softwareone.com/pt-br/blog/artigos/2020/01/22/multicloud-softwareone&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://azure.microsoft.com/pt-br/overview/what-are-private-public-hybrid-clouds/#overview"&gt;https://azure.microsoft.com/pt-br/overview/what-are-private-public-hybrid-clouds/#overview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pt.wikipedia.org/wiki/Aprisionamento_tecnol%C3%B3gico"&gt;https://pt.wikipedia.org/wiki/Aprisionamento_tecnol%C3%B3gico&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[pt-BR] DevOps e Computação em Nuvem - #1</title>
      <dc:creator>Adriana Ferreira Lima Shikasho</dc:creator>
      <pubDate>Fri, 25 Mar 2022 22:28:25 +0000</pubDate>
      <link>https://dev.to/dxwebster/pt-br-infraestrutura-e-computacao-em-nuvem-parte-1-360e</link>
      <guid>https://dev.to/dxwebster/pt-br-infraestrutura-e-computacao-em-nuvem-parte-1-360e</guid>
      <description>&lt;p&gt;Neste artigo, vamos conhecer a cultura &lt;strong&gt;DevOps&lt;/strong&gt; e falar rapidamente sobre os benefícios que ela oferece para o desenvolvimento de software.&lt;/p&gt;

&lt;p&gt;Além, disso, vamos aprender o que é a &lt;strong&gt;Computação em Nuvem&lt;/strong&gt; e conhecer os modelos de serviços Iaas, Paas e Saas oferecidos pelos provedores de cloud do mercado.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Cultura DevOps&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A vantagem do DevOps&lt;/li&gt;
&lt;li&gt;4 bases do DevOps&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cloud Computing&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modelos de serviços de Nuvem&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;blockquote&gt;
&lt;p&gt;Esse conteúdo foi baseado na Aula 1 de Infraestructure e Cloud Computing da &lt;a href="https://www.impacta.edu.br/mba/full-stack-developer"&gt;pós-graduação de MBA em Desenvolvimento FullStack da Impacta&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  1. Cultura DevOps
&lt;/h1&gt;

&lt;p&gt;Esse é mais um dos assuntos do mundo de TI que demonstra o quanto desenvolvedores não podem ser apenas máquinas de escrever códigos.&lt;/p&gt;

&lt;p&gt;Um dev que conhece pelo menos um pouco de arquitetura, infraestrutura, engenharia e hardware está sempre um passo a frente daquele que só pensa em linguagem. &lt;/p&gt;

&lt;p&gt;Quanto mais a gente se abre para conhecer o que está além do código, mais adquirimos habilidades e repertório para desenvolver com qualidade e segurança. &lt;/p&gt;

&lt;p&gt;Não é necessário ser especialista em todos os assuntos, mas é importante conhecer e aprender um pouco das responsabilidades de outras frentes.&lt;/p&gt;

&lt;p&gt;Mesmo não sendo nossa área de especialização, aprender do outro nos movimenta a agir com mais empatia.&lt;/p&gt;

&lt;p&gt;E é aí que podemos encaixar a cultura DevOps, que vem de certa forma para ajudar a resolver possíveis atritos entre as diversas camadas do mundo de TI com métodos, ferramentas e dialogando muito bem com a cultura ágil.&lt;/p&gt;

&lt;h2&gt;
  
  
  A vantagem do DevOps
&lt;/h2&gt;

&lt;p&gt;Vamos imaginar uma empresa que decide construir seu próprio Data Center. Para isso, precisou montar um bom espaço físico com sistema de refrigeração especializado, comprar vários servidores, hardwares de storage e rede, etc. &lt;/p&gt;

&lt;p&gt;Esta empresa ainda vai precisar contratar diversas pessoas para criar times responsáveis por manter e gerenciar toda essa infraestrutura física, como passar cabos, monitorar servidores, configurar redes.&lt;/p&gt;

&lt;p&gt;Além disso precisará de uma operação constante para atender demandas dos desenvolvedores como por exemplo criar servidores, subir aplicações, configurar máquinas e etc. &lt;/p&gt;

&lt;p&gt;Esses desenvolvedores tem seu próprio prazo a cumprir, assim como as operações e as demais áreas.&lt;/p&gt;

&lt;p&gt;Se nenhuma metodologia for implementada, esse processo que demanda muito tempo e recursos entre as operações pode até causar atritos entre as equipes, e trazer diversos tipos de prejuízos em vários níveis.&lt;/p&gt;

&lt;p&gt;A cultura DevOps vem então para ajudar a resolver esse atrito e, de maneira mais simples, seu objetivo é remover as barreiras entre as duas equipes tradicionalmente separadas em silos: devs e operações.&lt;/p&gt;

&lt;p&gt;Essa cultura traz métodos e ferramentas de modo a auxiliar as partes a trabalharem de forma linear, ágil e harmonizada, encurtando o intervalo entre a idealização do projeto e a entrega.&lt;/p&gt;

&lt;p&gt;É necessário uma mudança de mentalidade, entretanto, a longo prazo, deve-se verificar um aumento a eficiência na comunicação e integração entre as equipes de modo a otimizar a produtividade dos desenvolvedores e a confiabilidade das operações.&lt;/p&gt;

&lt;h2&gt;
  
  
  4 bases do DevOps
&lt;/h2&gt;

&lt;p&gt;De maneira prática, podemos separar o devOps em 4 bases, que conversam com o ciclo de vida do desenvolvimento de software. Vamos ver um pouquinho de cada uma dessas etapas. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cs0CCCbB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ujevvc3y419m3zd56xh5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cs0CCCbB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ujevvc3y419m3zd56xh5.png" alt="Image description" width="791" height="592"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Agile Development
&lt;/h3&gt;

&lt;p&gt;Etapa de desenvolvimento de forma iterativa e incremental com métodos ágeis. É a fase que requisitos, produto, backlogs, desenvolvimento, que usam os frameworks de trabalho como Scrum, Kanbam, etc. &lt;/p&gt;

&lt;h3&gt;
  
  
  Continuous Integration (CI)
&lt;/h3&gt;

&lt;p&gt;Etapa de junção do código produzido e avaliação da qualidade do repositório. Cada componente da equipe entrega uma parte do código e é preciso depois juntar tudo e trabalhar na consistência dele, utilizar métodos e ferramentas para avaliar se está bom, se funciona, se compila. &lt;strong&gt;Exemplos de ferramentas: Jenkins, Azure DevOps, CodePipeline, etc.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Continuous Testing (CT)
&lt;/h3&gt;

&lt;p&gt;Etapa de testes automatizados, como este de unidade, integraçao, aceitação para validar se aquilo que estamos levando para o usuário tem qualidade. Tem um casamento perfeito com a CI, o código está sendo compilado e testado o tempo todo. &lt;strong&gt;Exemplos de ferramentas: JUnit, Selenium, Appium, JMeter, etc.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Continuos Delivery (CD)
&lt;/h3&gt;

&lt;p&gt;É essa etapa que diz respeito a infraestrutura, que leva a aplicação a um ambiente (homol, prod). São utilizadas ferramentas e métodos para facilitar e trazer conforto a gestão da infra, como Infraestructure as code (IaC), Ferramentas de provisionamento e Gestão de Repositórios.  &lt;strong&gt;Exemplos de ferramentas: Terraform, Ansible, Docker, Kubernetes, Vagrant, etc.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Cloud Computing
&lt;/h1&gt;

&lt;p&gt;Clouding Computing é a prática desse processo que traz agilidade e redução e custo no provisionamento de infraestrutura e operação.&lt;/p&gt;

&lt;p&gt;Quando falamos de nuvem, falamos de um conforto e facilidade para gerenciar a infraestrutura, que demanda menos tempo, menos recursos humanos e traz cada vez mais segurança ao ciclo de vida dos sistemas. &lt;/p&gt;

&lt;p&gt;O IaC acaba sendo um processo que abstrai a infraestrutura, traz escabilidade conforme demanda, e controla a tolerância a falhas. Um exemplo prático do IaC, é escrever um arquivo, como se fosse uma receita de bolo. Por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Preciso ter 2 servidores com comunicação TCP

&lt;ul&gt;
&lt;li&gt;O servidor 1

&lt;ul&gt;
&lt;li&gt;é de aplicação web&lt;/li&gt;
&lt;li&gt;tem acesso a internet&lt;/li&gt;
&lt;li&gt;tem phyton&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;O servidor 2

&lt;ul&gt;
&lt;li&gt;é de banco de dados&lt;/li&gt;
&lt;li&gt;mySQL na versão tal&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Obviamente que na vida real não será escrito desta forma, mas esse é um exemplo do quão fácil seria configurar alguns servidores ao utilizar o desenvolvimento em nuvem. Agora conseguimos criar uma série de automações que não eram possíveis no passado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modelos de serviços de Nuvem
&lt;/h2&gt;

&lt;p&gt;O provedores de nuvem mais conhecidos e utilizados hoje em dia são Azure, AWS e Google Cloud Platform, e cada um tem seus próprios serviços, pacotes e consultorias.&lt;/p&gt;

&lt;p&gt;Entretanto, podemos elencar 3 modelos de serviços que encontramos em todos eles: Iaas, Saas e Paas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cx0SGRiH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/54b9dui8i2vvzy5usccp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cx0SGRiH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/54b9dui8i2vvzy5usccp.png" alt="Image description" width="708" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mas antes de conhece-los, vamos começar com uma analogia para ilustrar o modelo tradicional e nos dar base para entender os modelos em nuvem.&lt;/p&gt;

&lt;h3&gt;
  
  
  On-premise
&lt;/h3&gt;

&lt;p&gt;Vamos imaginar um cenário da compra de um carro próprio. Antes mesmo de começar a dirigir, é necessário que a pessoa tire carta, pague o IPVA, faça seguro, realize manutenção constante, coloque gasolina, etc. Ou seja, é preciso muito recurso e muito esforço antes mesmo de comprar o carro, e durante o uso desse transporte.&lt;/p&gt;

&lt;p&gt;Da mesma forma é quando a empresa tem o próprio data center, chamado de ambiente on-premise. É necessário desembolsar uma super grana para comprar servidor, para montar uma estrutura de refrigeração com ar-condicionado, sobrepiso, etc.&lt;/p&gt;

&lt;p&gt;Além disso, a empresa precisa de gente que saiba passar cabo, verificar energia elétrica, subir software, virtualizador, instalar java, python, msql dentro de uma máquina virtual.&lt;/p&gt;

&lt;p&gt;Entretanto, esse modelo é o que traz mais autonomia para a empresa, pois ela pode fazer o que quiser já que todos os recursos são próprios.&lt;/p&gt;

&lt;p&gt;Em seguida veremos os modelos de serviços de nuvem existentes, e quando mais a gente avança, menos autonomia a empresa vai ter ao contratar o serviço.&lt;/p&gt;

&lt;h3&gt;
  
  
  Iaas (Infraestructue as a Service)
&lt;/h3&gt;

&lt;p&gt;O modelo Iaas é a porta de entrada para o serviço de nuvem e é como se fosse um carro por assinatura onde não é necessário comprar o carro, mas pagar um valor mensal que já consta o uso do carro, IPVA, seguro, etc.&lt;/p&gt;

&lt;p&gt;A empresa recebe máquinas virtuais e a única coisa que precisará se preocupar é em colocar  ferramentas e softwares lá dentro.&lt;/p&gt;

&lt;p&gt;Da máquina virtual pra baixo, aqueles requisitos de data center como infraestrutura, refrigeração ou cabeamento fica por responsabilidade do serviço de nuvem contratado.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Responsabilidade do serviço de nuvem:&lt;/strong&gt; data center + máquinas virtuais&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responsabilidade do cliente:&lt;/strong&gt; receber as máquinas virtuais, fazer toda a instalação e gestão de ferramentas e usá-las para desenvolver os softwares&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Paas (Platform as a Service)
&lt;/h3&gt;

&lt;p&gt;O modelo Paas é como se fosse um taxi. Não é necessário se preocupar se tem gasolina, se tem seguro ou em pagar o IPVA, a única preocupação é informar o trajeto. Mas o carro não é próprio, então há menos liberdade.&lt;/p&gt;

&lt;p&gt;O Paas é quando o serviço de nuvem me entrega uma ferramenta como serviço. Como por exemplo, o ambiente para eu rodar meu java, um banco de dados já instalado e pronto para ser utilizado. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Responsabilidade do serviço de nuvem:&lt;/strong&gt; data center + máquinas virtuais + ferramentas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responsabilidade do cliente:&lt;/strong&gt; usar as ferramentas para desenvolver os softwares&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Saas (Software as a Service)
&lt;/h3&gt;

&lt;p&gt;O modelo Saas é como se fosse um ônibus. Assim como o taxi, não é necessário se preocupar com gasolina, IPVA ou seguro, entretanto, o ônibus não muda seu percurso pela demanda. É mais barato, mas há ainda menos liberdade.&lt;/p&gt;

&lt;p&gt;O Saas entrega software pronto para funcionar como serviço, como por exemplo Gmail, Google Meeting, Google Classroom. Não há controle nenhum sobre as features do software e nenhum tipo de personalização.&lt;/p&gt;

&lt;p&gt;Esse modelo também é multitenant (permite multilocação), ou seja, vários clientes podem ser acomodadas no mesmo servidor, mas cada um recebe seu próprio serviço e isolado. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Responsabilidade do serviço de nuvem:&lt;/strong&gt; data center + máquinas virtuais + ferramentas + software&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responsabilidade do cliente:&lt;/strong&gt; utilizar os softwares&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Continua na parte 2 👉🏼 &lt;a href="https://dev.to/dxwebster/pt-br-infraestrutura-e-computacao-em-nuvem-parte-2-4bnb"&gt;clique aqui&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;-- &lt;/p&gt;

&lt;p&gt;Referências:&lt;br&gt;
&lt;a href="https://csrc.nist.gov/publications/detail/sp/800-145/final"&gt;https://csrc.nist.gov/publications/detail/sp/800-145/final&lt;/a&gt;&lt;br&gt;
&lt;a href="https://br.pinterest.com/pin/766737905309531976/?mt=login"&gt;https://br.pinterest.com/pin/766737905309531976/?mt=login&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[pt-BR] Como Testar Consumo de API de uma Aplicação em React - #4</title>
      <dc:creator>Adriana Ferreira Lima Shikasho</dc:creator>
      <pubDate>Mon, 21 Feb 2022 21:20:58 +0000</pubDate>
      <link>https://dev.to/dxwebster/pt-br-parte-4-hands-on-como-testar-consumo-de-api-de-uma-aplicacao-em-react-2p51</link>
      <guid>https://dev.to/dxwebster/pt-br-parte-4-hands-on-como-testar-consumo-de-api-de-uma-aplicacao-em-react-2p51</guid>
      <description>&lt;p&gt;Já testamos um componente Button, um componente Link que tem evento de usuário, um hook que armazena o estado dos produtos e permite adição de itens no carrinho. Ufa, já vimos bastante coisa por aqui, não é?&lt;/p&gt;

&lt;p&gt;Agora, chegou a hora de testar se nossa aplicação faz a chamada à API da lista de produtos da loja e exibe o resultado na tela conforme o esperado.&lt;/p&gt;

&lt;p&gt;Se você não viu ainda como testar componentes e como testar hooks, recomendo ler a &lt;a href="https://dev.to/dxwebster/pt-br-parte-2-hands-on-como-implementar-testes-unitarios-no-react-25jg"&gt;parte 2&lt;/a&gt; e &lt;a href="https://dev.to/dxwebster/pt-br-parte-3-hands-on-como-testar-os-hooks-de-uma-aplicacao-em-react-54a9"&gt;parte 3&lt;/a&gt; deste material antes de prosseguir.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que será abordado:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Testando consumo de API&lt;/li&gt;
&lt;li&gt;Conclusão&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Testando consumo de API
&lt;/h2&gt;

&lt;p&gt;Como sempre, vamos analisar o código do componente &lt;code&gt;ProductsList&lt;/code&gt;. No &lt;code&gt;useEffect&lt;/code&gt;sem dependência, vemos que ele já executa a chamada a API 1x ao carregamento do componente e em seguida, monta o componente listando os &lt;code&gt;products&lt;/code&gt; que foi atualizado pela ação &lt;code&gt;setProducts&lt;/code&gt; disponíbilizada pelo hook &lt;code&gt;useCart&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../services/api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../models/Product&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Molecules&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../Molecules&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ProductsList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setProduts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getProducts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/products&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;setProduts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;getProducts&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Nossos&lt;/span&gt; &lt;span class="nx"&gt;Produtos&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Title&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Molecules&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ProductItem&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;))}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/List&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Container&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pensar em consumo de API e em lidar com dados pode assustar um pouco, mas lembra que eu falei que nos testes tudo é simulado ou "mockado"?&lt;/p&gt;

&lt;p&gt;Pois é, aqui também "mockaremos" os resultado da chamada a API, ou seja, os dados serão apenas um objeto que nós mesmos montaremos em uma variável &lt;code&gt;cartProductMock&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A para simular também uma chamada à API, utilizaremos uma feature de uma lib chamada &lt;code&gt;axios-mock-adapter&lt;/code&gt;, da qual permite essa simulação de um request utilizando o axios. (Você deve instalá-la como dependência usando npm ou yarn, ok?)&lt;/p&gt;

&lt;p&gt;Beleza, vamos ver como isso funciona:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;MockAdapter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios-mock-adapter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;act&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;waitFor&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@testing-library/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../services/api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ProductsList&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;cartProductMock&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../mocks/cartProductMock&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;MockAdapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ProductsList component tests&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;renders without crashing with request&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;act&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;apiMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/products&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;cartProductMock&lt;/span&gt; &lt;span class="p"&gt;}]);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getByText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ProductsList&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waitFor&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uau, a maioria dos métodos a gente já conhece!&lt;/p&gt;

&lt;p&gt;Podemos ver que temos o act que simula uma ação, neste caso utilizando um método onGet do apiMock. Temos o getByText, que já vimos várias vezes e no fim qual o resultado esperado, que como a maioria das vezes é que ele esteja na tela sendo exibido corretamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Eu particularmente não acho testes algo muito fácil, pois pensando que são a garantia do funcionamento da aplicação que desenvolvemos, acaba sendo um processo que requer muita responsabildiade, principalmente para evitar falso positivos ou negativos.&lt;/p&gt;

&lt;p&gt;Entretanto, saber que temos um recurso a mais que agrega confiabilidade ao nosso código e traz mais qualidade à aplicação é um tanto satisfatório, pois como devs sempre queremos buscamos nos aprimorar para cada vez fazer entregas melhores.&lt;/p&gt;

&lt;p&gt;Estudar e me desenvolver em testes para front-end tem sido meu objetivo atual, e esse foi meu primeiro estudo de testes, da qual abriu muito a minha mente e tenho certeza que é o primeiro passo de uma longa jornada de aprendizado.&lt;/p&gt;

&lt;p&gt;Obrigada por chegar até aqui, e caso esse conteúdo tenha sido relevante para você, não esqueça de deixar seu comentário ou compartilhar para que mais gente também possa aprender!&lt;/p&gt;




&lt;h3&gt;
  
  
  Referências:
&lt;/h3&gt;

&lt;p&gt;Esse conteúdo foi baseado no vídeo &lt;a href="https://youtu.be/wTrjx54wDgM%5D(https://youtu.be/wTrjx54wDgM)"&gt;“Treinamento: Como implementar testes unitários em React utilizando Jest”&lt;/a&gt; do canal da Zappts, feito pelo &lt;a href="https://www.linkedin.com/in/ccastrojr/"&gt;Cláudio Castro&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Confira o repositório com o projeto: &lt;a href="https://github.com/ccastrojr/react_unit_test"&gt;https://github.com/ccastrojr/react_unit_test&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>react</category>
    </item>
    <item>
      <title>[pt-BR] Como Testar Hooks de uma Aplicação em React - #3</title>
      <dc:creator>Adriana Ferreira Lima Shikasho</dc:creator>
      <pubDate>Mon, 21 Feb 2022 16:48:31 +0000</pubDate>
      <link>https://dev.to/dxwebster/pt-br-parte-3-hands-on-como-testar-os-hooks-de-uma-aplicacao-em-react-54a9</link>
      <guid>https://dev.to/dxwebster/pt-br-parte-3-hands-on-como-testar-os-hooks-de-uma-aplicacao-em-react-54a9</guid>
      <description>&lt;p&gt;Testes de hooks é algo que assusta muita gente, mas vamos tornar tudo mais simples a partir de agora!&lt;/p&gt;

&lt;p&gt;Vamos continuar implementando testes na nossa aplicação de carrinho de ecommerce. Caso você não tenha visto o início dessa parte mais prática, confira na &lt;a href="https://dev.to/dxwebster/pt-br-parte-2-hands-on-como-implementar-testes-unitarios-no-react-25jg"&gt;parte 2&lt;/a&gt; deste material.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que será abordado:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Testando Hooks&lt;/li&gt;
&lt;li&gt;Simulação e mocks&lt;/li&gt;
&lt;li&gt;Testando ações&lt;/li&gt;
&lt;li&gt;Testando um Componente que utiliza um Hook&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Testando Hooks
&lt;/h1&gt;

&lt;p&gt;O hook deste carrinho possui um contexto que nos fornece as ações de listar produtos, adicionar e remover os itens do carrinho e calcular o valor total dos itens.&lt;/p&gt;

&lt;p&gt;A ideia é criar pelo menos 1 teste para cada ação, e utilizar os estados fornecidos pelo contexto para adicionar os mocks. Vamos ver o código do contexto (Vou deixar comentado em código o que cada parte faz):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[...]&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;CartProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="c1"&gt;// Estado que armazena os produtos&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setProducts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CartItem&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// pega os items em local storage&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;itemsStorage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@UnitTest:cart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// se tiver items, retorna o valor como estado inicial&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;itemsStorage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;itemsStorage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Se não tiver, retorna e inicia vazio.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Atualiza Local Storage com um novo array de itens&lt;/span&gt;
  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@UnitTest:cart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
     &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CartItem&lt;/span&gt;&lt;span class="p"&gt;[]));&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Ação que adiciona um item no carrinho&lt;/span&gt;
 &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addToCart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="c1"&gt;// Verifica se esse produto já existe no carrinho&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;productReceived&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
     &lt;span class="p"&gt;);&lt;/span&gt;

     &lt;span class="c1"&gt;// Se sim, adiciona 1 na contagem do item existente&lt;/span&gt;
     &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;productReceived&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nx"&gt;productReceived&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="nx"&gt;setProducts&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;

     &lt;span class="c1"&gt;// Se não, inclui o item no array com 1 no contador.&lt;/span&gt;
     &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nx"&gt;setProducts&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}]);&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
 &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Simulações e mocks
&lt;/h2&gt;

&lt;p&gt;Certo! Agora, vamos implementar o primeiro teste deste hook que será a funcionalidade de pegar os itens que estão salvos em Local Storage.&lt;/p&gt;

&lt;p&gt;Lembrando que esses items são armazenados no estado &lt;code&gt;products&lt;/code&gt;, então o que esperamos neste teste, é que o e estado &lt;code&gt;products&lt;/code&gt; tenha um array com algum item adicionado.&lt;/p&gt;

&lt;p&gt;Esse teste vai se chamar getItems from LocalStorage. O código abaixo descreve esse teste, e você pode perceber que ele segue o mesmo padrão de escrita de testes que já aprendemos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;renderHook&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@testing-library/react-hooks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;waitFor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;act&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@testing-library/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CartProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useCart&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cart hook tests&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;get items from localStorage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// 1. renderizar o hook&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;renderHook&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;useCart&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CartProvider&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. fazer uma query ou mock&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;itemAddedToCart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some_value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Product Test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image_path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// 3. executar alguma ação&lt;/span&gt;
    &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;getItem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mockImplementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@ReactUnitTest:cart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;itemAddedToCart&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// 4. descrever o resultado esperado&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waitFor&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Product Test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;renderHook&lt;/code&gt;: como hook não é um componente, utilizamos esse método para renderizar o Hook e conseguir pegar o resultado dele. Neste caso, importamos o useCart e o envolvemos pelo seu provider o CartProvider.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;result&lt;/code&gt;: pega o resultado de alguma ação ou estado que veio do contexto. No caso, pegar o estado &lt;code&gt;products&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;jest.spyOn&lt;/code&gt;: faz a simulação de alguma funcionalidade, neste caso simulamos o Local Storage.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mockImplementation&lt;/code&gt;: implementa um mock na simulação, neste caso, implementamos o mock de item na simulação de LocalStorage&lt;/p&gt;

&lt;p&gt;&lt;code&gt;waitFor&lt;/code&gt;: espera por um resultado.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;expect&lt;/code&gt;: descreve o resultado esperado, aqui nós esperamos que o resultado, ou seja, que o array &lt;code&gt;products&lt;/code&gt; tenha um item com o nome igual ao que passamos no mock.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testando ações
&lt;/h2&gt;

&lt;p&gt;Nosso próximo teste do hook será sobre adicionar items no carrinho. Queremos garantir que a function &lt;code&gt;addToCart&lt;/code&gt; está funcionando corretamente.&lt;/p&gt;

&lt;p&gt;O início será bem parecido com o teste anterior, da qual vamos renderizar o hook e criar um mock do item. O resultado esperado também será o mesmo, o que vai mudar aqui vai ser justamente o fato de que queremos testar uma açao do hook. Vamos ver como fica:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;get items from localStorage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// 1. renderizar o hook&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;renderHook&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;useCart&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CartProvider&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. fazer uma query ou mock&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;itemAddedToCart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some_value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Product Test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image_path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// 3. executar alguma ação&lt;/span&gt;
    &lt;span class="nx"&gt;act&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addToCart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;itemAddedToCart&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// 4. descrever o resultado esperado&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waitFor&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Product Test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;act&lt;/code&gt;: faz com que a renderização seja o mais próximo possível do que acontece no Browser. Neste caso, chamamos no método act a ação que queremos testar e passamos pra ela o mock como parâmetro.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;expect&lt;/code&gt;: se tudo ocorrer bem, o resultado também será um array &lt;code&gt;products&lt;/code&gt; com 1 item adicionado.&lt;/p&gt;

&lt;p&gt;O hook ainda tem duas ações para ser testadas: removeToCart e getTotalPrice. Entretanto, fica como desafio, pois da pra fazer baseado naquilo que já vimos aqui. &lt;/p&gt;

&lt;h2&gt;
  
  
  Testando um Componente que utiliza um Hook
&lt;/h2&gt;

&lt;p&gt;Ok, testamos duas funcionalidades do hook useCart e agora vamos testar um componente que utiliza esse hook, o próprio carrinho de compras. Como sempre, vamos olhar o código do componente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ReactComponent&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;CartIcon&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../assets/cart.svg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useCart&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../hooks/Cart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Cart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useCart&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/cart&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;testid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cart_link_component&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CartIcon&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Container&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você se lembra qual o primeiro teste que costumamos escrever quando testamos um componente? Isso mesmo, testamos se ele está sendo exibido corretamente na tela. &lt;/p&gt;

&lt;p&gt;Entretanto, como esse componente utiliza o hook useCart, não podemos simplesmente testar como já fizemos nos anteriores. Aqui nós precisaremos mockar o hook, já que o componente depende dele.&lt;/p&gt;

&lt;p&gt;Vamos utilizar o mesmo método que usamos para simular o LocalStorage, o &lt;code&gt;jest.spyOn&lt;/code&gt;. E para mockar também o retorno do hook, vamos passar um objeto pelo método &lt;code&gt;mockReturnValue&lt;/code&gt; com o estado &lt;code&gt;products&lt;/code&gt; e as ações que o hook disponibiliza.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BrowserRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@testing-library/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;hookCart&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../hooks/Cart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cart component tests&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;renders without crashing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hookCart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;useCart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;mockReturnValue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
      &lt;span class="na"&gt;addToCart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;removeToCart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;getTotalPrice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getByTestId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Cart&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BrowserRouter&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

   &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cart_link_component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;import *&lt;/code&gt;: vamos importar tudo que vem do hook para simular&lt;/p&gt;

&lt;p&gt;&lt;code&gt;jest.spyOn&lt;/code&gt;: passando o que foi importado, vamos simular o hook useCart e mockar no mockReturnValue seus valores.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;expect&lt;/code&gt;: utilizamos o mesmo método anterior de getByTestId e esperamos que o componente esteja na tela. &lt;/p&gt;

&lt;h3&gt;
  
  
  👉 Veja como testar consumo de API na &lt;a href="https://dev.to/dxwebster/pt-br-parte-4-hands-on-como-testar-consumo-de-api-de-uma-aplicacao-em-react-2p51"&gt;parte 4&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Referências:
&lt;/h3&gt;

&lt;p&gt;Esse conteúdo foi baseado no vídeo &lt;a href="https://youtu.be/wTrjx54wDgM%5D(https://youtu.be/wTrjx54wDgM)"&gt;“Treinamento: Como implementar testes unitários em React utilizando Jest”&lt;/a&gt; do canal da Zappts, feito pelo &lt;a href="https://www.linkedin.com/in/ccastrojr/"&gt;Cláudio Castro&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Confira o repositório com o projeto: &lt;a href="https://github.com/ccastrojr/react_unit_test"&gt;https://github.com/ccastrojr/react_unit_test&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>react</category>
    </item>
    <item>
      <title>[pt-BR] Como Testar Componentes de uma Aplicação em React - #2</title>
      <dc:creator>Adriana Ferreira Lima Shikasho</dc:creator>
      <pubDate>Mon, 21 Feb 2022 16:39:10 +0000</pubDate>
      <link>https://dev.to/dxwebster/pt-br-parte-2-hands-on-como-implementar-testes-unitarios-no-react-25jg</link>
      <guid>https://dev.to/dxwebster/pt-br-parte-2-hands-on-como-implementar-testes-unitarios-no-react-25jg</guid>
      <description>&lt;h3&gt;
  
  
  O que será abordado:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Primeiros passos&lt;/li&gt;
&lt;li&gt;Enxergando Padrões&lt;/li&gt;
&lt;li&gt;Escrevendo o primeiro teste de Componente&lt;/li&gt;
&lt;li&gt;Testanto Componentes que possuem dependências&lt;/li&gt;
&lt;li&gt;Testando um evento de usuário no Componente&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Primeiros passos
&lt;/h1&gt;

&lt;p&gt;Vamos imaginar uma aplicação bem simples que simula um ecommerce. Nela teremos duas páginas:&lt;/p&gt;

&lt;p&gt;Home: que é a loja que lista todos os produtos. Cada item pode ser adicionado no carrinho ao clique de um botão.&lt;/p&gt;

&lt;p&gt;Cart: que é o próprio carrinho da qual podemos ver os itens que foram adicionados para compra e excluí-los caso desejado.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Você encontra o repositório com o projeto &lt;a href="https://github.com/ccastrojr/react_unit_test"&gt;aqui&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ao longo da aplicação temos alguns botões, e um deles é o que usamos para adicionar algum item no carrinho. Por isso foi criado um componente único de botão. Vamos ver esse código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Button.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ButtonHTMLAttributes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLButtonElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;large&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;data-testid&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"pure_button"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para incluir um teste para esse componente, vamos criar na mesma pasta um arquivo Button.spec.tsx&lt;/p&gt;

&lt;h2&gt;
  
  
  Enxergando Padrões
&lt;/h2&gt;

&lt;p&gt;De maneira didática e para nos ajudar a lembrar como deve ser a estrutura de escrita cada teste, podemos pensar em seguir o seguinte padrão:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Renderizar o componente passando suas props&lt;/li&gt;
&lt;li&gt;Fazer uma query ou um mock&lt;/li&gt;
&lt;li&gt;Executar alguma ação&lt;/li&gt;
&lt;li&gt;Descrever o resultado esperado&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Uma outra dica que podemos manter em mente é sempre pensar que basicamente tudo em testes é uma simulação. Seria como se fosse uma réplica das funcionalidades, só que todos os dados e ações são "mockados" ou simplesmente falsos. &lt;/p&gt;

&lt;p&gt;O objetivo é montar o teste de forma que replique de maneira simulada determinada funcionalidade, mas utilizando as ferramentas que a lib de testes provê. Mas vamos aos poucos que daqui a pouco começa a ficar mais claro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Escrevendo o primeiro teste de Componente
&lt;/h2&gt;

&lt;p&gt;O título desta suite será “Button component tests” (Testes do componente Button), e o primeiro teste, verificaremos se este componente está sendo exibido corretamente na tela. Esse tipo de teste é o mais básico, e pode ser o primeiro teste para qualquer componente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Button.spec.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@testing-library/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Button component tests&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;renders without crashing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"default"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pure_button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao enxergar o padrão que explicamos anteriormente, percebemos que neste caso em específico não precisaremos executar nenhuma ação (item 3), mas veremos um exemplo com ação mais pra frente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;  &lt;span class="p"&gt;[...]&lt;/span&gt;    

  &lt;span class="c1"&gt;// 1. renderizar o componente passando suas props&lt;/span&gt;
  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"default"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. fazer a query do componente&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pure_button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// 4. descrever o resultado esperado&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="p"&gt;[...]&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;describe&lt;/code&gt;&lt;/strong&gt;: descreve um conjunto de testes que estão associados. O describe por si só não executa teste, ele só agrupa os testes de determinado componente. Ele recebe 2 parâmetros: um texto que descreve a suite de testes, e uma função callback. Nessa função, vamos escrever cada teste.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;test ou it&lt;/code&gt;&lt;/strong&gt;: implementa o teste. Também recebe 2 parâmetros: um texto bem descritivo do teste, e uma função callback com a execução do teste de fato.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;render&lt;/code&gt;&lt;/strong&gt;: usado para identificar qual componente da aplicação que queremos renderizar para testar. Ele precisa receber as props obrigatórias desse compontent. O render retorna vários métodos para fazermos a query desse component. Uma delas é a getByTestId.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;getByTestId&lt;/code&gt;&lt;/strong&gt;: para usar essa função é necessario ter o atributo data-testid no componente que queremos testar. Ele é um atributo único que vai nos ajudar a fazer a query do componente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;expect&lt;/code&gt;:&lt;/strong&gt; o que a gente espera que aconteça. Neste caso, a gente espera que o botão esteja no documento, ou seja, que seja renderizado corretamente, então utilizamos o método &lt;strong&gt;&lt;code&gt;toBeInTheDocument()&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testanto componentes que possuem dependências
&lt;/h2&gt;

&lt;p&gt;Beleza, já temos nosso primeiro teste, o mais simples deles, agora vamos começar a nos aprofundar um pouco mais. Lembrando na nossa aplicação sendo um ecommerce, nós temos um Link (chamado MenuOption) no menu superior da home que vai nos redirecionar para a página de carrinho.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LinkProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;LinkProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;MenuOption&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt;&lt;span class="nx"&gt;LinkProps&lt;/span&gt; &lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;MenuOption&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O primeiro teste, será o mesmo que escrevemos para o botão, mas veremos uma outra forma de fazer a query do nosso componente MenuOption.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MenuOption component tests&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;renders without crashing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// 1. renderizar o componente passando suas props&lt;/span&gt;
    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MenuOption&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Link Teste"&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. fazer a query do componente&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Link Teste&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// 4. descrever o resultado esperado&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como podemos ver, fizemos a query utilizando o getByText, em que podemos pegar algum texto que está aparecendo na tela. &lt;/p&gt;

&lt;p&gt;Neste caso, o MenuOption exibe um texto que recebe no parâmetro label, entretanto, aqui no teste podemos “mockar” qualquer texto, pois o importante é a query funcionar, e não precisa ser exatamente como na aplicação.&lt;/p&gt;

&lt;p&gt;Então vamos passar como parâmetro o &lt;code&gt;label='Link Teste'&lt;/code&gt; e vamos usar essa mesma string na query &lt;code&gt;getByText('Link Teste')&lt;/code&gt; para selecioná-lo.&lt;/p&gt;

&lt;p&gt;Não podemos esquecer de passar no render, todos os parâmetros obrigatórios para aquele componente. Por exemplo, o MenuOption sendo um &lt;code&gt;Link&lt;/code&gt; que veio do react-router-dom, ele obrigatoriamente precisa que seja passado um &lt;code&gt;to='/'&lt;/code&gt;, se não dá erro.&lt;/p&gt;

&lt;p&gt;Feito isso, escrevemos o resultado esperado, que é que o componete esteja no documento, conforme já vimos.&lt;/p&gt;

&lt;p&gt;Ok, agora vamos rodar nosso teste. Executamos yarn test, e... percebemos que não passou! Ué, o que fizemos de errado?&lt;br&gt;
Vamos verificar qual a mensagem de erro que aparece no console:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Invariant failed: You should not use &amp;lt;Link&amp;gt; outside a &amp;lt;Router&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Mas o que isso significa?&lt;/p&gt;

&lt;p&gt;Um componente Link para que ele possa ser renderizado, eu preciso ter por volta dele um Router que é o responsável pelo redirecionamento, sem ele, o link não funciona.&lt;/p&gt;

&lt;p&gt;Para resolver isso,  vamos envolvê-lo passando um segundo parâmetro no método render, que é um objeto com um wrapper. E dentro do wrapper passamos o &lt;code&gt;BrowserRouter&lt;/code&gt;, que é o resposável por criar as rotas e fazer o Link funcionar.&lt;/p&gt;

&lt;p&gt;O teste correto vai ficar assim agora:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;[...]&lt;/span&gt;

&lt;span class="c1"&gt;// no render passaremos o objeto com wrapper: BrowserRouter&lt;/span&gt;
&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MenuOption&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Link Teste"&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BrowserRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="p"&gt;[...]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora sim! Ao rodar os testes, ele vai passar, pois não teremos nenhum problema de dependência para a renderização do componente.&lt;/p&gt;

&lt;p&gt;Então ótimo, agora já aprendemos que toda vez que aparecer essa mensagem de erro de que algum componente não pode ser renderizado fora de outro componente, já sabemos que precisamos “envolvê-lo” com esse componente da qual ele tem dependência.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testando um evento de usuário no Componente
&lt;/h2&gt;

&lt;p&gt;Certo, como prometemos, vamos ver um exemplo que agora contém os 4 pontos que definimos no nosso padrão de escrita lá trás, que é alguma ação.&lt;/p&gt;

&lt;p&gt;Nesse mesmo componente MenuOption, lembrando que ele é um Link e todo link serve para navegação, e normalmente isso é feita através de um clique do usuário no link.&lt;/p&gt;

&lt;p&gt;Por isso, nosso próximo teste será verificar se o redirecionamento para a próxima página está funcionando ao clique do usuário no link. Vamos escreve-lo, acrescentando o método &lt;code&gt;userEvent.click()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;o método userEvent, descreve exatamente isso, uma ação ou evento feita pelo usuário e pode ser obtida pela importação do &lt;code&gt;'@testing-library/user-event’&lt;/code&gt;. Vai ficar assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click to redirect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. renderizar o componente passando suas props&lt;/span&gt;
    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MenuOption&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Button Test"&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/url"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BrowserRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. fazer a query do componente&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Link Teste&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// 3. executar alguma ação&lt;/span&gt;
    &lt;span class="nx"&gt;userEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// 4. descrever o resultado esperado&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/url&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois do clique o usuário teremos um resultado esperado propício a um link: queremos que aconteça um redirect para uma outra página. E qual será essa página? Será a string que passamos nas prop &lt;code&gt;to&lt;/code&gt; que definimos no render do MenuOption, neste caso, &lt;code&gt;to='/url'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Então lá no expect, vamos usar um método do próprio javascript que  pega o pathname da url, o método &lt;code&gt;global.window.location.pathname&lt;/code&gt;, e esperamos que ele seja igual a string que deifinimos na prop, utilizando o método &lt;code&gt;toEqual('/url')&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  👉 Veja como testar hooks na &lt;a href="https://dev.to/dxwebster/pt-br-parte-3-hands-on-como-testar-os-hooks-de-uma-aplicacao-em-react-54a9"&gt;parte 3&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Referências:
&lt;/h3&gt;

&lt;p&gt;Esse conteúdo foi baseado no vídeo &lt;a href="https://youtu.be/wTrjx54wDgM%5D(https://youtu.be/wTrjx54wDgM)"&gt;“Treinamento: Como implementar testes unitários em React utilizando Jest”&lt;/a&gt; do canal da Zappts, feito pelo &lt;a href="https://www.linkedin.com/in/ccastrojr/"&gt;Cláudio Castro&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Confira o repositório com o projeto: &lt;a href="https://github.com/ccastrojr/react_unit_test"&gt;https://github.com/ccastrojr/react_unit_test&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>react</category>
    </item>
    <item>
      <title>[pt-BR] Fundamentos de Testes Unitários no Front-end - #1</title>
      <dc:creator>Adriana Ferreira Lima Shikasho</dc:creator>
      <pubDate>Mon, 21 Feb 2022 16:38:55 +0000</pubDate>
      <link>https://dev.to/dxwebster/pt-br-parte-1-fundamentos-de-testes-unitarios-no-front-end-1i3d</link>
      <guid>https://dev.to/dxwebster/pt-br-parte-1-fundamentos-de-testes-unitarios-no-front-end-1i3d</guid>
      <description>&lt;p&gt;Os testes unitários são os testes mais básicos da cadeia de testes no desenvolvimento de software.&lt;/p&gt;

&lt;p&gt;Diferentemente dos outros tipos de teste (integração e e2e), os testes unitários, também chamados de teste de unidade, garantem que uma pequena unidade esteja funcionando mesmo desconectada de todo o restante da aplicação.&lt;/p&gt;

&lt;p&gt;Eles nos ajudam a garantir uma entrega com maior qualidade, visto que podem ser rodados sempre que uma nova implementação for feita no código e garantir que nada esteja quebrado antes do deploy.&lt;/p&gt;

&lt;p&gt;Veremos neste conteúdo, os fundamentos básicos da implementação de testes unitários em React, utilizando a a react-testing-library. Você pode consultar no final da página a referência utilizada para produção deste conteúdo.&lt;/p&gt;

&lt;p&gt;Este conteúdo esta dividido em 4 partes, sendo esta a parte mais teórica e as demais são práticas, em que você aprenderá:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Como testar componentes&lt;/li&gt;
&lt;li&gt;Como testar hooks&lt;/li&gt;
&lt;li&gt;Como testar chamadas a APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nesta série nos preocuparemos mais no "&lt;em&gt;como testar&lt;/em&gt;", qual ferramenta ou qual método utilizar. Mas se você quiser expandir ainda mais seu conhecimento sobre testes, recomendo que você leia esta série sobre "&lt;em&gt;o que testar&lt;/em&gt;" no front-end. Confira &lt;a href="https://dev.to/dxwebster/series/16968"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que será abordado:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Testes unitários no front-end&lt;/li&gt;
&lt;li&gt;A responsabilidade de um componente&lt;/li&gt;
&lt;li&gt;Prevenindo falsos-positivos&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Testes unitários no front-end
&lt;/h1&gt;

&lt;p&gt;Antes de ir para a parte prática, vamos entender como os testes unitários se aplicam a interface, a começar por uma simples analogia:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A estrutura de um front-end de uma aplicação web poderia ser comparada a um quebra-cabeça. Se uma das peças se quebrar de forma que não possa mais ser encaixada a outra peça, a imagem ficará comprometida e a peça quebrada precisará ser consertada.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Se tratando de front-end, as peças são os componentes e o quebra-cabeça é a aplicação. Embora seja comum componentes quebrarem durante o desenvolvimento, não queremos de forma alguma que nossos componentes estejam quebrados em produção. Seria um desastre!&lt;/p&gt;

&lt;p&gt;E para evitar isso, implementamos testes unitários em cada componente, de forma a garantir que tudo está funcionando bem.&lt;/p&gt;

&lt;p&gt;Entretanto, para escrever bons testes no front-end, o código também deve ser bem escrito, a lógica dos componentes também deve ser bem pensada.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A qualidade dos testes andam de mãos dadas com a qualidade dos componentes!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  A responsabilidade de um componente
&lt;/h3&gt;

&lt;p&gt;Se lembrarmos do princípio da responsabilidade única, em que uma classe ou componente, deve ter uma única e exclusiva responsabilidade, podemos melhorar a qualidade do componente. &lt;/p&gt;

&lt;p&gt;Entretanto, caso um componente ainda esteja com mais reponsabilidades do que deveria, os testes vão nos ajudar a identificar.&lt;/p&gt;

&lt;p&gt;Se ao escrever testes percebermos que será necessário testar duas funcionalidades em um mesmo componentes, já é um alerta de que possivelmente teremos que dividí-lo em dois componentes distintos.&lt;/p&gt;

&lt;p&gt;Um exemplo prático seria algo como, um componente button que também tem a função de navegação. Pensando em boas práticas de desenvolvimento, isso não seria algo certo, pois botão é botão e link é link.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prevenindo falsos-positivos
&lt;/h3&gt;

&lt;p&gt;Os testes uniários também nos ajudam a prevenir falsos-positivos. Ao dar manutençao e testar uma única rotina, podemos pensar que tudo está funcionando bem, quando na realidade podem ainda haver bugs em nosso código.&lt;/p&gt;

&lt;p&gt;Vamos supor que alteramos alguma coisa no componente B, e precisamos saber se gerou alguma alteracao no componente A. É muito comum testarmos manualmente apenas o componente A e não testar o componente B ou até mesmo outros módulos que o utilizam. &lt;/p&gt;

&lt;p&gt;Acabamos assumindo que tudo está funcionando, quando na realidade pode ter algo quebrado. Assim, os testes unitários rodando antes de cada deploy, testam tanto o componente A que sofreu manutenção, quanto o componente B que usa o componente A e garante se tudo ainda está funcionando conforme o esperado.&lt;/p&gt;

&lt;h3&gt;
  
  
  👉 Vamos ver agora na prática? Leia a &lt;a href="https://dev.to/dxwebster/pt-br-parte-2-hands-on-como-implementar-testes-unitarios-no-react-25jg"&gt;parte 2&lt;/a&gt;
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Referências:
&lt;/h3&gt;

&lt;p&gt;Esse conteúdo foi baseado no vídeo &lt;a href="https://youtu.be/wTrjx54wDgM%5D(https://youtu.be/wTrjx54wDgM)"&gt;“Treinamento: Como implementar testes unitários em React utilizando Jest”&lt;/a&gt; do canal da Zappts, feito pelo &lt;a href="https://www.linkedin.com/in/ccastrojr/"&gt;Cláudio Castro&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Confira o repositório com o projeto: &lt;a href="https://github.com/ccastrojr/react_unit_test"&gt;https://github.com/ccastrojr/react_unit_test&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>react</category>
    </item>
    <item>
      <title>[pt-BR] Testes de Caso de Uso no React - #3</title>
      <dc:creator>Adriana Ferreira Lima Shikasho</dc:creator>
      <pubDate>Mon, 07 Feb 2022 14:39:38 +0000</pubDate>
      <link>https://dev.to/dxwebster/pt-br-testes-sao-fundamentais-mas-como-saber-o-que-testar-parte-3-5da0</link>
      <guid>https://dev.to/dxwebster/pt-br-testes-sao-fundamentais-mas-como-saber-o-que-testar-parte-3-5da0</guid>
      <description>&lt;p&gt;Por muitas vezes ao pensar em testes do React, já pensamos direto em testes de detalhes de implementação. E já vimos por &lt;a href="https://dev.to/dxwebster/pt-br-testes-sao-fundamentais-mas-como-saber-o-que-testar-parte-1-13f"&gt;aqui&lt;/a&gt; o quando esse caminho pode acabar mascarando erros, ou atrapalhando a produtividade por serem muito frágeis.&lt;/p&gt;

&lt;p&gt;Portanto, para aplicar os Testes de Caso de Uso no React, podemos sempre pensar em qual efeito observável que aquele código que quero testar tem para os nossos usuários como por exemplo, partes relacionadas a Métodos de ciclo de vida, Eventos dos elementos ou Estado interno de componentes.&lt;/p&gt;

&lt;p&gt;Vamos ver aqui algumas técnicas práticas a pensar que vão para facilitar a implementação de testes em uma aplicação em React.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que será abordado:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Como aplicar Testes de Caso de Uso no React?&lt;/li&gt;
&lt;li&gt;React Testing Library&lt;/li&gt;
&lt;li&gt;Conclusão&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Como aplicar Testes de Caso de Uso no React?
&lt;/h1&gt;

&lt;p&gt;Provavelmente isso não é uma regra, mas podemos divir algumas partes do código do React pensando a que tipo de usuário ela se refere. Por exemplo:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O usuário-final&lt;/strong&gt; vê e interage com aquilo que renderizamos, ou seja, tudo o que está dentro do render ou return.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O usuário-desenvolvedor&lt;/strong&gt; vê e interage com os adereços que passamos para os componentes, como props, estados, contextos. &lt;/p&gt;

&lt;p&gt;Também temos elementos que precisamos testar e que são preocupantes para &lt;strong&gt;ambos&lt;/strong&gt;, como por exemplo mudança na DOM, uma chamada HTTP, chamadas callback, ou outros tipo de efeitos colaterais que são observáveis como:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interações do usuário&lt;/strong&gt;: O usuário final é capaz de interagir com os elementos que o componente renderiza?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mudanças de props&lt;/strong&gt;: O que acontece quando o usuário-desenvolvedor re-renderiza o componente com novas props?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mudanças de contexto&lt;/strong&gt;: O que acontece quando o usuário desenvolvedor altera o contexto, resultando na rerenderização do seu componente? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alterações de subscription&lt;/strong&gt;: O que acontece quando um emissor de evento relacionado a algum componente muda? (Como firebase, uma store do redux, uma rota, uma media query ou assinaturas baseadas em navegador, como status online)&lt;/p&gt;

&lt;h1&gt;
  
  
  React Testing Library
&lt;/h1&gt;

&lt;p&gt;Essa é uma ferramenta criada exclusivamente com o objetivo de escrever testes para manutenção de componentes React de forma que evite testar detalhes de implementação e manter a aplicação sustentável a longo prazo.&lt;/p&gt;

&lt;p&gt;Vamos ver um exemplo de teste utilizando o React Testing Library, utilizando o mesmo exemplo do accordion que usamos na &lt;a href="https://dev.to/dxwebster/pt-br-testes-sao-fundamentais-mas-como-saber-o-que-testar-parte-1-13f"&gt;parte 1&lt;/a&gt;, só que vamos reescrevê-lo em functional component com hooks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// accordion.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Accordion&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;openIndexes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setOpenIndex&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setOpenIndex&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;])}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;openIndexes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AccordionContents&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/AccordionContents&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;))}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora escrevemos o teste, pensando no comportamento observável do componente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Pode abrir items do accordion e ver seus conteúdos"
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pode abrir items do accordion e ver seus conteúdos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Chapéu Favorito&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Fedoras são legais&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;footware&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Calçado Favorito&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Chinelos são os melhores&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Accordion&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt; &lt;span class="nx"&gt;hats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;footware&lt;/span&gt;  &lt;span class="p"&gt;]}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queryByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;footware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="nx"&gt;userEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;footware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;footware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queryByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;not&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Incrível! Agora temos um único teste que verifica todo o comportamento do componente. E esse teste vai passar mesmo se o nome do estados for &lt;code&gt;openIndex&lt;/code&gt;, &lt;code&gt;openIndexes&lt;/code&gt;, ou &lt;code&gt;tacosAreTasty&lt;/code&gt;, não importa!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Acredito que é seguro dizer que normalmente os desenvolvedores não tem tanta vontade assim de escrever testes, muito menos seguindo metolodogias como TDD, BDD, FDD, DDD ou outras.&lt;/p&gt;

&lt;p&gt;Entretanto, todos sabem da sua real importância e acredito que essa cultura de só codar sem implementar testes vai acabar ficando pra trás, pois sabemos o quanto contribui para a confiabilidade do código e isso é o que todo mundo quer!&lt;/p&gt;

&lt;p&gt;Já vi gente dizer que escrever testes pra front-end é um caos, pois não existia padrão ou alguma ferramenta mais simples de configurar.&lt;/p&gt;

&lt;p&gt;Entretanto, como vimos nesse material, já não está mais tão ruim assim implementar os testes no front-end e espero que surjam cada vez mais autores como o &lt;a href="https://kentcdodds.com/about"&gt;Kent C. Dodds&lt;/a&gt; para trazer essas abordagens práticas de testes no front-end.&lt;/p&gt;

&lt;p&gt;Além disso, as ferramentas tem avançado também como vimos com o React Test Library, e diversas outras como o Enzime, e o Jest sendo este o mais popular, talvez por ser nativo do create-react-app.&lt;/p&gt;

&lt;p&gt;Por fim, agora que aprendemos "o que" testar, podemos facilmente integrar esse conhecimento com o estudo dessas ferramentas e melhorar ainda mais a qualidade nos nossos testes.&lt;/p&gt;

&lt;p&gt;Caso queira conhecer agora o "como" testar, deixo algumas recomendações abaixo que podem introduzir o assunto: &lt;/p&gt;

&lt;p&gt;"Guia rápido de testes no front-end" - Thayse Onofrio&lt;br&gt;
 &lt;a href="https://dev.to/thayseonofrio/guia-rapido-de-testes-no-front-end-2lpc"&gt;https://dev.to/thayseonofrio/guia-rapido-de-testes-no-front-end-2lpc&lt;/a&gt;&lt;br&gt;
"Testes automatizados em React" - Thiago Ferreira&lt;br&gt;
&lt;a href="https://medium.com/luizalabs/testes-automatizados-em-react-e431db826d65"&gt;https://medium.com/luizalabs/testes-automatizados-em-react-e431db826d65&lt;/a&gt;&lt;br&gt;
"Jest: Escrever testes nunca foi tão divertido" - Eduardo Rabelo&lt;br&gt;
&lt;a href="https://oieduardorabelo.medium.com/jest-escrever-testes-nunca-foi-t%C3%A3o-divertido-5f0e1950ba10"&gt;https://oieduardorabelo.medium.com/jest-escrever-testes-nunca-foi-t%C3%A3o-divertido-5f0e1950ba10&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Referências:&lt;/strong&gt;&lt;br&gt;
"How to know what to test" - Kent C. Dodds &lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/how-to-know-what-to-test"&gt;https://kentcdodds.com/blog/how-to-know-what-to-test&lt;/a&gt;&lt;br&gt;
"Avoid the Test User" - Kent C. Dodds &lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/avoid-the-test-user"&gt;https://kentcdodds.com/blog/avoid-the-test-user&lt;/a&gt;&lt;br&gt;
"Testing Implementation Details" - Kent C. Dodds &lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/testing-implementation-details"&gt;https://kentcdodds.com/blog/testing-implementation-details&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[pt-BR] Conheça a melhor forma de escrever testes no seu front-end - #2</title>
      <dc:creator>Adriana Ferreira Lima Shikasho</dc:creator>
      <pubDate>Mon, 07 Feb 2022 14:38:15 +0000</pubDate>
      <link>https://dev.to/dxwebster/pt-br-testes-sao-fundamentais-mas-como-saber-o-que-testar-parte-2-1mhc</link>
      <guid>https://dev.to/dxwebster/pt-br-testes-sao-fundamentais-mas-como-saber-o-que-testar-parte-2-1mhc</guid>
      <description>&lt;p&gt;Como vimos na Parte 1, testar detalhes de implementação no front-end pode ser uma armadilha que pode acabar mascarando erros gerando falso-positivos ou falso-negativos ou até mesmo atrapalhando a produtividade por serem muito frágeis.&lt;/p&gt;

&lt;p&gt;Vamos então abordar de maneira prática um caminho para se pensar em testes no front-end de forma que eles se tornem mais confiáveis e com mais qualidade.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que será abordado:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Testando Casos de Uso&lt;/li&gt;
&lt;li&gt;Cobertura de Código&lt;/li&gt;
&lt;li&gt;Cobertura de Casos de Uso&lt;/li&gt;
&lt;li&gt;Quando a Cobertura de Código oculta os Casos de Uso&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Testando Casos de Uso
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;"Quanto mais seus testes se assemelham à forma como seu software é usado, mais confiança eles podem lhe dar." - Kent C. Dodds&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essa é a natureza dos testes de casos de uso, pensar em escrever testes que atendam a forma que nossos dois usuários** (usuário-final e usuário-desenvolvedor) usam e interagem com nossa aplicação.&lt;/p&gt;

&lt;p&gt;**&lt;em&gt;ver Detalhes de implementação da &lt;a href="https://dev.to/dxwebster/pt-br-testes-sao-fundamentais-mas-como-saber-o-que-testar-parte-1-13f"&gt;parte 1&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Escrevemos testes para ter certeza de que nosso aplicativo funcionará quando o usuário os usar e principalmente melhorar a confiança da aplicação.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Pense menos no código que você está testando e mais nos casos de uso que o código suporta." - Kent C. Dodds&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Cobertura de Código
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Cobertura de código&lt;/em&gt; é a métrica que nos mostra quais linhas do nosso código estão rodando durante o teste. Vamos utilizar esse código como exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;verificaArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sem incluir teste para essa função, o relatório vai indicar que 0% de &lt;em&gt;Cobertura de código&lt;/em&gt; nos dando a ideia de quanta parte do código ainda falta cobrir.&lt;/p&gt;

&lt;p&gt;O relatório de &lt;em&gt;Cobertura de código&lt;/em&gt; não diz exatamente qual a importância da função &lt;code&gt;verificaArray&lt;/code&gt; ou nem mesmo diz os casos de uso que ela atende.&lt;/p&gt;

&lt;p&gt;Mas quando consideramos a aplicação inteira, mesmo o relatório de &lt;em&gt;Cobertura de código&lt;/em&gt; não nos dando uma a visão completa, ele nos ajuda a identificar quais testes poderiam ser adicionados para atender os casos de uso da aplicação.&lt;/p&gt;

&lt;h1&gt;
  
  
  Cobertura de Casos de Uso
&lt;/h1&gt;

&lt;p&gt;A &lt;em&gt;Cobertura de Casos de Uso&lt;/em&gt; nos diz quantos casos de uso nosso teste atende. Voltando ao código de exemplo, podemos identificar o primeiro &lt;strong&gt;caso de uso&lt;/strong&gt; da função &lt;code&gt;verificaArray&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Retorna um array se o argumento for um array".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Obs: Há uma convenção de escrever os títulos dos testes em inglês, entretanto neste estudo, vou escrevê-los em português-BR por uma questão didática, beleza?&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Retorna um array se o argumento for um array&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;verificaArray&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Elefante&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Girafa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Elefante&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Girafa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E com esse teste escrito, nosso relatório de &lt;em&gt;Cobertura de Código&lt;/em&gt; vai parecer com algo do tipo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;verificaArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;          &lt;span class="c1"&gt;// coberto&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="c1"&gt;// coberto&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assim, se olharmos para as linhas que faltam, vamos concluir que são mais dois &lt;strong&gt;casos de Uso&lt;/strong&gt; que faltam ser cobertos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Retorna um array vazio se o argumento tiver um valor falso"&lt;/li&gt;
&lt;li&gt;"Retorna um array se o argumento não for um array e não for falso"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos adicionar os testes para esses &lt;strong&gt;casos de uso&lt;/strong&gt;, e ver como isso afeta a &lt;em&gt;Cobertura de Código&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Retorna um array vazio se o argumento tiver um valor falso&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;verificaArray&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="s2"&gt;`Retorna um array se o argumento não for um array e não for falso`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;verificaArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Leopardo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Leopardo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cobertura:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;verificaArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;          &lt;span class="c1"&gt;// coberto&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt; &lt;span class="c1"&gt;// coberto&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;             &lt;span class="c1"&gt;// coberto&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;                    &lt;span class="c1"&gt;// coberto&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ótimo! Agora temos 100% de cobertura de código, mas também 100% de cobertura de casos de uso e podemos confiar que, enquanto não mudarmos os casos de uso dessa função, nossos testes vão continuar passando.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quando a cobertura de código oculta os casos de uso
&lt;/h2&gt;

&lt;p&gt;As vezes, o relatório de &lt;em&gt;Cobertura de código&lt;/em&gt; pode indicar 100% de cobertura, mas não 100% de cobertura de casos de uso.&lt;/p&gt;

&lt;p&gt;Esse é o motivo que é bom ter a prática de pensar em todos os casos de uso possíveis antes mesmo de começar a escrever os testes.&lt;/p&gt;

&lt;p&gt;Por exemplo, vamos imaginar que a function &lt;code&gt;verificaArray&lt;/code&gt; foi implementada desse jeito:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;verificaArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;         
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;array&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                   
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso, nós temos 100% de cobertura com apenas os 2 casos de uso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retorna um array se o argumento for um array&lt;/li&gt;
&lt;li&gt;Retorna um array se o argumento não for um array&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Entretanto, se olharmos para o relatório de &lt;em&gt;Cobertura de caso de uso&lt;/em&gt;, podemos perceber que está faltando um caso de uso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retorna um array vazio se o argumento tiver um valor falso&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E isso é um mau sinal, pois mesmo se o usuário user a função &lt;code&gt;verificaArray&lt;/code&gt; sem passar nenhum argumento, os testes vão continuar passando, mas o código vai quebrar.&lt;/p&gt;

&lt;p&gt;E essa é justamente uma das razões que implementamos testes, garantir que o código continue atendendo aos casos de uso que desejamos incluir. &lt;/p&gt;

&lt;p&gt;Por exemplo, se um outro dev remover o &lt;code&gt;.filter(Boolean)&lt;/code&gt;, os testes ainda continuam passando, mas qualquer código que dependia do resultado da function como sendo "falso", vai quebrar. &lt;/p&gt;

&lt;h3&gt;
  
  
  👉 Continue lendo na &lt;a href="https://dev.to/dxwebster/pt-br-testes-sao-fundamentais-mas-como-saber-o-que-testar-parte-3-5da0"&gt;parte 3&lt;/a&gt;
&lt;/h3&gt;




&lt;p&gt;&lt;strong&gt;Referências:&lt;/strong&gt;&lt;br&gt;
"How to know what to test" - Kent C. Dodds &lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/how-to-know-what-to-test"&gt;https://kentcdodds.com/blog/how-to-know-what-to-test&lt;/a&gt;&lt;br&gt;
"Avoid the Test User" - Kent C. Dodds &lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/avoid-the-test-user"&gt;https://kentcdodds.com/blog/avoid-the-test-user&lt;/a&gt;&lt;br&gt;
"Testing Implementation Details" - Kent C. Dodds &lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/testing-implementation-details"&gt;https://kentcdodds.com/blog/testing-implementation-details&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[pt-BR] Quer testar sua interface? Entenda o que não fazer - #1</title>
      <dc:creator>Adriana Ferreira Lima Shikasho</dc:creator>
      <pubDate>Mon, 07 Feb 2022 14:37:24 +0000</pubDate>
      <link>https://dev.to/dxwebster/pt-br-testes-sao-fundamentais-mas-como-saber-o-que-testar-parte-1-13f</link>
      <guid>https://dev.to/dxwebster/pt-br-testes-sao-fundamentais-mas-como-saber-o-que-testar-parte-1-13f</guid>
      <description>&lt;p&gt;Os testes compõe uma parte fundamental no processo de desenvolvimento de software. Apesar disso, muita gente acha os testes desagradáveis, principalmente os testes de interface.&lt;/p&gt;

&lt;p&gt;Existem várias razões para isso, mas das mais comuns é que fazer e manter os testes gastam muito tempo. "Toda vez que faço uma alteração no código, os testes quebram!"&lt;/p&gt;

&lt;p&gt;E no fim, de certa forma estão até corretas, porque testes quebrando o tempo todo é um grande empecilho para a produtividade. Entretanto, e se eu te disser que existe algumas formas de evitar essas frustrações e começar a implementar testes de interface mais confiáveis?&lt;/p&gt;

&lt;p&gt;Quando estudamos testes, sendo pra front ou back, por muitas vezes nos preocupamos em conhecer seus fundamentos ou quais ferramentas utilizar, ou seja, tópicos que tem mais a ver com "como" implementar os testes do que "o que" realmente testar.&lt;/p&gt;

&lt;p&gt;De acordo com &lt;a href="https://kentcdodds.com/about"&gt;Kent C. Dodds&lt;/a&gt;, definir muito bem "o que" testar é o ponto-chave para agregar mais valor e confiabilidade aos testes.&lt;/p&gt;

&lt;p&gt;O conteúdo desse artigo utiliza como referência alguns textos do Dodds e está dividido em 3 partes: a primeira descreve o que não fazer ao escrever testes para o front-end; na segunda parte, veremos qual a melhor prática para escrever testes confiáveis e por fim, na última parte, veremos um pouco de como pensar os testes seguindo estrutura de código do React.&lt;/p&gt;

&lt;p&gt;Você pode conferir as referências ao final de cada parte destes posts.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que será abordado:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Porque fazer testes?&lt;/li&gt;
&lt;li&gt;Detalhes de implementação&lt;/li&gt;
&lt;li&gt;Falso-negativo&lt;/li&gt;
&lt;li&gt;Falso-positivo&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Porque fazer testes?
&lt;/h1&gt;

&lt;p&gt;Em termos gerais, fazemos testes para que tenhamos sempre a confiança de que a aplicação vai funcionar como esperado quando o usuário a utilizar.&lt;/p&gt;

&lt;p&gt;E pensando no usuário e como ele utiliza a aplicação, podemos chegar em uma metodologia que vai nos guiar a escrever testes e garantir que tragam cada vez mais confiança:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Pensar menos sobre linhas de código e mais sobre &lt;em&gt;Casos de Uso&lt;/em&gt; que o código atende." - Kent C. Dodds&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Quando pensamos apenas sobre linhas de código ao invés de pensar em casos de uso, fica muito fácil nos perdemos e começarmos a nos preocupar em testar "detalhes de implementação", o que logo mais veremos que é uma pratica que pode gerar consequencias ruins ao desenvolvimento.&lt;/p&gt;

&lt;p&gt;Por isso, antes mesmo de nos aprofundarmos nos testes de caso de uso que é basicamente "o que" devemos testar, vamos ver o que NÃO devemos testar na aplicação.&lt;/p&gt;

&lt;h1&gt;
  
  
  Detalhes de implementação
&lt;/h1&gt;

&lt;p&gt;De maneira simples, podemos definir os detalhes de implementação como:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Coisas que os usuários do seu código normalmente não usarão, verão ou sequer conhecerão." - Kent C. Dodds&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E quem são os usuários do nosso código? Bom, quando escrevemos código, precisamos manter em mente que devemos atender apenas a 2 tipos de usuários:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O usuário-final&lt;/strong&gt;: é aquele que interage com o componente (por exemplo, insere valores em inputs de um form, clica no botão enviar ou reset, recebe mensagem de carregamento e success)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O usuário-desenvolvedor&lt;/strong&gt;: é o que renderiza o componente (por exemplo, inclui o componente em um UserProvider para atualizar seu estado e fazer dispatch pra o contexto)&lt;/p&gt;

&lt;p&gt;Entretanto, quando fazemos testes de detalhes de implementação, acaba surgindo um terceiro usuário, que é o usuário-tester. Esse tipo de usuário não deve ter atendido, pois criando testes pra eles, faremos com que esses testes não se assemelhem à forma que a aplicação é usada pelos usuários que são importantes.&lt;/p&gt;

&lt;p&gt;Há duas razões distintas pelas quais é importante evitar testar detalhes de implementação:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Pode quebrar quando você refatora o código do aplicativo, gerando &lt;em&gt;Falso-negativo&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pode acabar não falhando quando o código quebrar, gerando  &lt;em&gt;Falso-positivo&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Vamos para um exemplo em React, utilizando um componente accordion simples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// accordion.js&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Accordion&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;openIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;setOpenIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;openIndex&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;openIndex&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;openIndex&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setOpenIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;openIndex&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AccordionContents&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/AccordionContents&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;))}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Accordion&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora um teste utilizando a ferramenta Enzyme, para testar os &lt;em&gt;detalhes de implementação&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// __tests__/accordion.enzyme.js&lt;/span&gt;
&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;setOpenIndex sets the open index state properly&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Accordion&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[]}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;openIndex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;setOpenIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;openIndex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, agora vamos entender como as coisas quebram fácil com esse tipo de teste.&lt;/p&gt;

&lt;h2&gt;
  
  
  Falso-negativo
&lt;/h2&gt;

&lt;p&gt;Digamos que seja necessário refatorar este accordion a permitir que vários itens sejam abertos de uma só vez. Agora, vamos fazer essa alteração na &lt;em&gt;implementação&lt;/em&gt; de modo que não altere seu &lt;em&gt;comportamento&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// accordion.js&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Accordion&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;openIndexes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
  &lt;span class="nx"&gt;setOpenIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;openIndex&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;openIndexes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;openIndex&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;openIndexes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setOpenIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;openIndexes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AccordionContents&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/AccordionContents&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;))}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Accordion&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Legal! Agora a gente abre a aplicação e ve que tudo está funcionando corretamente, conforme desejamos e caso desejemos replica-lo também será muito fácil.&lt;/p&gt;

&lt;p&gt;Aí, vamos rodar os testes eles travaram. Vemos que o teste que quebrou foi: &lt;code&gt;setOpenIndex sets the open index state properly&lt;/code&gt;. E a mensagem de erro é a seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;expect&lt;span class="o"&gt;(&lt;/span&gt;received&lt;span class="o"&gt;)&lt;/span&gt;.toBe&lt;span class="o"&gt;(&lt;/span&gt;expected&lt;span class="o"&gt;)&lt;/span&gt;

Expected value to be &lt;span class="o"&gt;(&lt;/span&gt;using &lt;span class="o"&gt;===)&lt;/span&gt;: 0
Received: undefined
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa falha no teste está nos alertando sobre um problema real? Não! Pois o componente ainda está funcionando.&lt;/p&gt;

&lt;p&gt;Isso é o que se chama de &lt;strong&gt;falso negativo&lt;/strong&gt;. Isso significa que tivemos uma falha no teste, mas foi por causa de um teste quebrado, não porque o código está quebrado. &lt;/p&gt;

&lt;p&gt;Bem, a solução então para esse caso é alterar o teste:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;setOpenIndex sets the open index state properly&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Accordion&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[]}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;)
&lt;/span&gt;  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;openIndexes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;setOpenIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;openIndexes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chegamos então à primeira conclusão que testar detalhes de implementação podem gerar falso-negativo quando há alguma refatoração no código, o que torna os testes frágeis e frustantes que parecem falhar em simplesmente olhar o código.&lt;/p&gt;

&lt;h2&gt;
  
  
  Falso-positivo
&lt;/h2&gt;

&lt;p&gt;Ok, agora vamos dizer que seu colega de trabalho está trabalhando no accordion e ele vê este código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setOpenIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imediatamente, pensando prematuramente em otimizar ele pensa: "Ei! Arrow functions inline são ruins para performance! Vou corrigir aqui rapidinho e fazer os testes."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setOpenIndex&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aí ele faz os testes e, tcharam! Passaram! Aí sem mesmo olhar no navegador o componente funcionando, ele manda abre um PR, é aprovado e o accordion quebra em produção!&lt;/p&gt;

&lt;p&gt;Mas o que deu errado? O teste verificava se o estado mudava quando o &lt;code&gt;setOpenIndex&lt;/code&gt; era chamado e se o conteúdo era exibido corretamente. Sim, está correto, o problema é que não houve teste para verificar se evento onClick do botão estava chamando o &lt;code&gt;setOpenIndex&lt;/code&gt; corretamente.&lt;/p&gt;

&lt;p&gt;Isso é chamado de falso positivo, o que significa que o teste não falhou mas deveria ter falhado! Então, o que podemos fazer para garantir que não ocorra novamente?&lt;/p&gt;

&lt;p&gt;Poderíamos pensar em algumas ações como: adicionar outro teste para verificar se clicar no botão atualiza o estado corretamente ou simplesmente usar uma ferramenta gratuita que nos auxilia a evitar testar detalhes de implementação.&lt;/p&gt;

&lt;p&gt;Eu gosto dessa segunda alternativa, aposto que você também! Veremos esses detalhes na parte 3 em que falamos sobre os testes no React!&lt;/p&gt;

&lt;p&gt;Mas por enquanto, vamos seguir a linha de raciocínio e aprender sobre os testes que realmente devemos nos preocupar em escrever: "Testes de caso de uso".&lt;/p&gt;

&lt;h3&gt;
  
  
  👉 Continue lendo na &lt;a href="https://dev.to/dxwebster/pt-br-testes-sao-fundamentais-mas-como-saber-o-que-testar-parte-2-1mhc"&gt;parte 2&lt;/a&gt;
&lt;/h3&gt;




&lt;p&gt;&lt;strong&gt;Referências:&lt;/strong&gt;&lt;br&gt;
"How to know what to test" - Kent C. Dodds &lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/how-to-know-what-to-test"&gt;https://kentcdodds.com/blog/how-to-know-what-to-test&lt;/a&gt;&lt;br&gt;
"Avoid the Test User" - Kent C. Dodds &lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/avoid-the-test-user"&gt;https://kentcdodds.com/blog/avoid-the-test-user&lt;/a&gt;&lt;br&gt;
"Testing Implementation Details" - Kent C. Dodds &lt;br&gt;
&lt;a href="https://kentcdodds.com/blog/testing-implementation-details"&gt;https://kentcdodds.com/blog/testing-implementation-details&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
