<?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: Gustavo Cardoso </title>
    <description>The latest articles on DEV Community by Gustavo Cardoso  (@gusstavocardoso).</description>
    <link>https://dev.to/gusstavocardoso</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%2F633421%2F214ab4a7-8ad9-45e7-a03c-84d3bca84383.jpeg</url>
      <title>DEV Community: Gustavo Cardoso </title>
      <link>https://dev.to/gusstavocardoso</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gusstavocardoso"/>
    <language>en</language>
    <item>
      <title>Testando API com Unirest em Node.js</title>
      <dc:creator>Gustavo Cardoso </dc:creator>
      <pubDate>Thu, 22 Feb 2024 19:33:55 +0000</pubDate>
      <link>https://dev.to/gusstavocardoso/testando-api-com-unirest-em-nodejs-j11</link>
      <guid>https://dev.to/gusstavocardoso/testando-api-com-unirest-em-nodejs-j11</guid>
      <description>&lt;p&gt;Olhando o code snippet no Postman, me deparei com exemplos usando Unirest em Node.js. Fiquei curioso e resolvi dar uma olhada mais de perto.&lt;/p&gt;

&lt;p&gt;Unirest é uma biblioteca HTTP client, desenvolvida e mantida pelo Kong, disponível em várias linguagens.&lt;/p&gt;

&lt;p&gt;A documentação do &lt;a href="https://github.com/Kong/unirest-nodejs"&gt;Unirest Node.js&lt;/a&gt; contém vários exemplos de Requests e Responses com a descrição de uso.&lt;/p&gt;

&lt;p&gt;Com base nos exemplos, criei um projeto simples de testes automatizados de API. O framework de teste utilizado foi o &lt;a href="https://vitest.dev/"&gt;Vitest&lt;/a&gt; entre outras dependências como: &lt;em&gt;dotenv&lt;/em&gt; e o &lt;em&gt;prettier&lt;/em&gt; , para gerenciamento de variáveis de ambiente e formatação de código, respectivamente.&lt;/p&gt;




&lt;h3&gt;
  
  
  Iniciando o projeto
&lt;/h3&gt;

&lt;p&gt;Assumindo que Node.js está ou foi instalado na máquina, podemos dar inicio ao projeto.&lt;br&gt;
Crie o diretório com o nome e local que desejar, acesse-o, inicie um projeto node e instale as dependências.&lt;/p&gt;

&lt;p&gt;No diretório do projeto execute o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com o arquivo package.json presente, instale as dependências:&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install unirest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -D vitest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Prettier - Opcional para este exemplo
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev --save-exact prettier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Definindo a estrutura
&lt;/h3&gt;

&lt;p&gt;Como disse é um projeto simples, motivado por curiosidade e estudo pessoal e aplicação de conhecimento.&lt;/p&gt;

&lt;p&gt;Apesar de simples, serve como &lt;em&gt;boilerplate&lt;/em&gt; e claro adaptar e escalar de acordo com a necessidade. &lt;/p&gt;

&lt;p&gt;Incialmente o projeto está organizado em dois diretórios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;data&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Destinado a criação de dados em &lt;strong&gt;JSON&lt;/strong&gt; utilizado nos testes. Use essa massa dados exemplificada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "books": {
    "create": {
      "firstname": "Richard",
      "lastname": "Bandler",
      "totalprice": 111,
      "depositpaid": true,
      "bookingdates": {
        "checkin": "2018-01-01",
        "checkout": "2019-01-01"
      },
      "additionalneeds": "Breakfast"
    },
    "update": {
      "firstname": "John",
      "lastname": "Grinder",
      "totalprice": 111,
      "depositpaid": true,
      "bookingdates": {
        "checkin": "2018-01-01",
        "checkout": "2019-01-01"
      },
      "additionalneeds": "Breakfast"
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;tests&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aqui encontra-se o os arquivos de testes. Onde podemos organizar, como preferirmos. Nesse exemplo, criei apenas uma arquivo, no padrão &lt;code&gt;.test.js&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Tendo apenas um arquivo, agrupei os testes dentro de uma suíte, então ficou dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;describe("Testing restful-booker API with Unirest", () =&amp;gt; {
  test("Should generate token", async () =&amp;gt; {

  });

  test("Should register a book", async () =&amp;gt; {

  });
...
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Implementando os testes
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;API&lt;/strong&gt; usada no projeto foi a  &lt;a href="https://restful-booker.herokuapp.com/apidoc/index.html"&gt;restful-booker&lt;/a&gt; bem conhecida pela comunidade, para fins de estudo. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Criando o arquivo .env&lt;/strong&gt;&lt;br&gt;
Antes de adentrar aos testes crie na raiz do projeto o arquivo &lt;code&gt;.env&lt;/code&gt; com as variáveis e seus valores, conforme a documentação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BASE_URL=https://restful-booker.herokuapp.com
USERNAME=admin
PASSWORD=password123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Imports e variáveis&lt;/strong&gt;&lt;br&gt;
Próximo passo é o &lt;em&gt;import&lt;/em&gt; das &lt;em&gt;libs&lt;/em&gt; e declaração das variáveis, ficando dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { describe, expect, test } from 'vitest';
const unirest = require('unirest');
const { books } = require('../data/books.json');
const dotenv = require('dotenv');
dotenv.config({ override: true });

let token;
let bookingId;

const BASE_URL = process.env.BASE_URL;
const USERNAME = process.env.USERNAME;
const PASSWORD = process.env.PASSWORD;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O primeiro teste é um método &lt;strong&gt;POST&lt;/strong&gt; para criação do &lt;em&gt;token&lt;/em&gt;, que será atribuído ao &lt;em&gt;cookie&lt;/em&gt; em outros métodos. &lt;/p&gt;

&lt;p&gt;Por ser uma estrutura base, mantive a autenticação como um teste. Uma melhor opção, pensando na evolução do projeto, seria criar uma função com a finalidade de obter o &lt;em&gt;token&lt;/em&gt; e usa-lá sempre que precisarmos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test('Should generate token', async () =&amp;gt; {
    await unirest
      .post(`${BASE_URL}/auth`)
      .headers({
        Accept: 'application/json',
        'Content-Type': 'application/json',
      })
      .send({ username: USERNAME, password: PASSWORD })
      .then(function (res) {
        token = res.body.token;
        expect(res.status).toBe(200);
      });
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O próximo teste é o registro de um livro(&lt;em&gt;book&lt;/em&gt;), também com o método &lt;strong&gt;POST&lt;/strong&gt;. Neste usamos a massa de dados passando o &lt;em&gt;path&lt;/em&gt; &lt;code&gt;books.create&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; test('Should register a book', async () =&amp;gt; {
    await unirest
      .post(`${BASE_URL}/booking`)
      .headers({
        'Content-Type': 'application/json',
        Accept: 'application/json',
      })
      .send(JSON.stringify(books.create))
      .then(function (res) {
        bookingId = res.body.bookingid;
        expect(res.status).toBe(200);
      });
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora é o teste de atualização de livros(&lt;em&gt;book&lt;/em&gt;) com o método &lt;strong&gt;PUT&lt;/strong&gt;. Usaremos massa de dados de &lt;code&gt;books.update&lt;/code&gt; e conforme requerido o &lt;em&gt;token&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; test('Should update a book', async () =&amp;gt; {
    await unirest
      .put(`${BASE_URL}/booking/${bookingId}`)
      .headers({
        Accept: 'application/json',
        'Content-Type': 'application/json',
        Cookie: `token=${token}`,
      })
      .send(JSON.stringify(books.update))
      .then(function (res) {
        expect(res.status).toBe(200);
      });
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finalizando com método &lt;strong&gt;DELETE&lt;/strong&gt; onde é passado o &lt;code&gt;bookingid&lt;/code&gt; no &lt;em&gt;path&lt;/em&gt; da URL. Esse valor é obtido no &lt;em&gt;response&lt;/em&gt; ao criarmos um livro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test('Should remove a book', async () =&amp;gt; {
    await unirest
      .delete(`${BASE_URL}/booking/${bookingId}`)
      .headers({
        Accept: 'application/json',
        'Content-Type': 'application/json',
        Cookie: `token=${token}`,
      })
      .then(function (res) {
        expect(res.status).toBe(201);
      });
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Executando os testes
&lt;/h3&gt;

&lt;p&gt;Além de asserções de &lt;em&gt;status code&lt;/em&gt;, podemos fazer outras, então explore a vontade de acordo com os objetivos de cada teste.&lt;/p&gt;

&lt;p&gt;No &lt;code&gt;package.json&lt;/code&gt; adicione aos scripts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"scripts": {
    "test": "vitest"
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No terminal execute o comando:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;O &lt;em&gt;output&lt;/em&gt; com o resultado dos testes será esse:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffqtdelh7xcgd5q1jt2k0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffqtdelh7xcgd5q1jt2k0.png" alt="Image description" width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Concluindo
&lt;/h3&gt;

&lt;p&gt;Minha principal intenção com esse material, além de contribuir de alguma forma com a comunidade, foi a organização das informações, aplicação e transferência de conhecimento.&lt;/p&gt;

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