<?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: Arthur Valentim Kasper</title>
    <description>The latest articles on DEV Community by Arthur Valentim Kasper (@arthurvkasper).</description>
    <link>https://dev.to/arthurvkasper</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%2F724361%2F53884a9e-52c8-476a-9523-346c2ea0f459.png</url>
      <title>DEV Community: Arthur Valentim Kasper</title>
      <link>https://dev.to/arthurvkasper</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arthurvkasper"/>
    <language>en</language>
    <item>
      <title>How to test external APIs with Webmock and VCR in RSpec</title>
      <dc:creator>Arthur Valentim Kasper</dc:creator>
      <pubDate>Sat, 14 Oct 2023 14:08:53 +0000</pubDate>
      <link>https://dev.to/arthurvkasper/how-to-test-external-apis-with-webmock-and-vcr-in-rspec-4ha5</link>
      <guid>https://dev.to/arthurvkasper/how-to-test-external-apis-with-webmock-and-vcr-in-rspec-4ha5</guid>
      <description>&lt;p&gt;Let’s talk about how we can test &lt;strong&gt;external APIs&lt;/strong&gt; in our applications using Webmock and VCR, for this post, I‘ll use the RSpec suite. I’ll be very straightforward and minimalist in this explanation&lt;/p&gt;

&lt;p&gt;💎 &lt;em&gt;The examples will be done in a Rails app&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🌐 Webmock&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/bblimke/webmock"&gt;webmock&lt;/a&gt; gem allows us to create stubs for HTTP requests, in other words, you can create fake returns for some internet service, without making the real request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting
&lt;/h3&gt;

&lt;p&gt;Adding to gem file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"webmock"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the &lt;code&gt;spec/scpec_helper.rb&lt;/code&gt; file, add the following &lt;code&gt;require&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'webmock/rspec'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the bundle install to install the gem&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, the HTTP requests are disabled and the Webmock will always request the stubs of the responses, but making these stubs for all APIs can be tired, so for this, we will use VCR, which will do this “automatically” for us, so let’s see how we can do this.&lt;/p&gt;

&lt;h2&gt;
  
  
  📼 VCR
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/vcr/vcr"&gt;VCR gem&lt;/a&gt; records the interaction of API calls for future usage, in other words, VCR creates a stub for us, making the real call only once and recording it in a file, to use for the next calls without making the real call again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting
&lt;/h3&gt;

&lt;p&gt;Adding to Gemfile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"vcr"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding the code block inside of &lt;code&gt;spec/scpec_helper.rb&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;VCR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cassette_library_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"spec/fixtures/cassettes"&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hook_into&lt;/span&gt; &lt;span class="ss"&gt;:webmock&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure_rspec_metadata!&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The property &lt;code&gt;cassette_library_dir&lt;/code&gt; is about the path where the result of the APIs will be recorded, the &lt;code&gt;hook_into&lt;/code&gt; is about Webmock (which we talked about in the previous topic) to disable the HTTP requests when necessary and the &lt;code&gt;configure_rspec_metadata!&lt;/code&gt; allow us to use a property in our RSpec tests to keep them more simple using VCR, when we look at the code it will be more clear.&lt;/p&gt;

&lt;h2&gt;
  
  
  👨‍💻Testing
&lt;/h2&gt;

&lt;p&gt;To show all the things I’ll make a simple get API call to &lt;strong&gt;JSON Placeholder&lt;/strong&gt; in my test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;'ServiceApi'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;'get a post'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:vcr&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'jsonplaceholder.typicode.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'/posts/1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;code&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt; &lt;span class="s1"&gt;'200'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that in the &lt;code&gt;it&lt;/code&gt;, I just add a &lt;code&gt;:vcr&lt;/code&gt; argument, basicly with this I already informed the RSpec that the test will use the VCR, In case you had a multiple test, it’s possible add the :vcr argument directly in the &lt;code&gt;describe&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When we ran the test, we have the following situation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;failures&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It passes as expected, note that a file was generated in the path that we set in &lt;code&gt;cassette_library_dir&lt;/code&gt; property with the name of the test, it shows that the VCR made a request and recorded the response in an yml file, now, the next time that this test runs, the RSpec will get the data from this file instead made a real API call, in case you need regenerate the response, just delete the file and rerun the test.&lt;/p&gt;

&lt;p&gt;Cool, right? This is a very simple way to work with external APIs in our tests and ensure that we will not have intermittent fails.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>api</category>
      <category>testing</category>
      <category>rspec</category>
    </item>
    <item>
      <title>Com testar APIs externas com Webmock e VCR no RSpec</title>
      <dc:creator>Arthur Valentim Kasper</dc:creator>
      <pubDate>Sat, 14 Oct 2023 12:00:19 +0000</pubDate>
      <link>https://dev.to/arthurvkasper/com-testar-apis-externas-com-webmock-e-vcr-no-rspec-pt-br-7jg</link>
      <guid>https://dev.to/arthurvkasper/com-testar-apis-externas-com-webmock-e-vcr-no-rspec-pt-br-7jg</guid>
      <description>&lt;p&gt;Bora falar como podemos testar &lt;strong&gt;API externas&lt;/strong&gt; a nossa aplicação em nossas aplicações utilizando Webmock e VCR, para este artigo estarei usando a suite de teste RSpec. Vou tentar ser bem minimalista e direto nas explicações*.*&lt;/p&gt;

&lt;p&gt;💎 &lt;em&gt;Os exemplos serão feitos em um app Rails&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;🌐 Webmock&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;O &lt;a href="https://github.com/bblimke/webmock"&gt;webmock&lt;/a&gt; é uma gem que nos permite criar stubs de chamadas HTTP, ou seja, ela permite criar retornos falsos para algum serviço de internet, mas sem fazer a chamada real. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Configurando&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Adicionar no Gemfile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"webmock"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dentro do seu arquivo spec/spec_helper adicionar o seguinte &lt;code&gt;require&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'webmock/rspec'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rodar bundle install para instalar a gem&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;bundle&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso as sua chamadas HTTP já ficam desabilitadas e o Webmock exigira que você realiza o stub dos retornos, mas fazer esses mocks/retornos para toda nova API que vamos testar pode ser tornar chato e cansativo, nesta parte que entra o VCR, que vai fazer isso “automagicamente” para nós, bora ver como isso pode ser feito.&lt;/p&gt;

&lt;h2&gt;
  
  
  📼 VCR
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://github.com/vcr/vcr"&gt;gem VCR&lt;/a&gt; grava as iterações de suas chamadas para que o resultado dessas chamadas sejam utilizados no futuro, em outras palavras ela cria o stub para nós, realizando a chamada real uma única vez, após isso utiliza esse resultado para os testes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Configurando&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Adicionar no Gemfile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"vcr"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adicionar esse trecho de código dentro de &lt;em&gt;spec_helpers&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;VCR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cassette_library_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"spec/fixtures/cassettes"&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hook_into&lt;/span&gt; &lt;span class="ss"&gt;:webmock&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure_rspec_metadata!&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A propriedade &lt;code&gt;cassette_library_dir&lt;/code&gt; se refere ao local onde os retornos das APIs serão armazenados, já a &lt;code&gt;hook_into&lt;/code&gt; nos diz que o webmock (que vimos no tópico anterior) é usado para desabilitar as chamadas http quando necessário e o &lt;code&gt;configure_rspec_metadata!&lt;/code&gt; possibilita adicionar uma propriedade em nossos testes rspec para deixa-los menos verbosos ao usar o VCR, quando formos para o código isso ficará mais claro.&lt;/p&gt;

&lt;h2&gt;
  
  
  👨‍💻Testando
&lt;/h2&gt;

&lt;p&gt;Para testar vou realizar uma simples chamada get para a API do &lt;strong&gt;JSON Placeholder&lt;/strong&gt; em meu teste.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;'ServiceApi'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;'get a post'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:vcr&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'jsonplaceholder.typicode.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'/posts/1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;code&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt; &lt;span class="s1"&gt;'200'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba que no meu &lt;code&gt;it&lt;/code&gt;, eu adicionei o argumento &lt;code&gt;:vcr&lt;/code&gt;, basicamente com isso eu já informo para o RSpec que o teste usará o VCR, caso vc tenha multiplos teste, é possível adicionar o argumento diretamente no &lt;code&gt;describe&lt;/code&gt; de seu teste.&lt;/p&gt;

&lt;p&gt;Ao rodar o teste, temos a seguinte situação&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;failures&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ele passou como esperado, peceba que foi gerado um arquivo no diretório que configuramos na propriedade &lt;code&gt;cassette_library_dir&lt;/code&gt; do VCR com o nome do teste, isso demontra que o VCR fez a chamada e armazenou o conteúdo num arquivo yml, agora as próximas vezes que esse mesmo teste for executado, o RSpec vai consultar este arquivo (que pode ser chamado de cassete) e não realizará uma chamada real, caso você precise regerar o arquivo, basta excluílo e rodar o teste novamente.&lt;/p&gt;

&lt;p&gt;Bacana né? Essa é uma forma bem simples de trabalharmos com APIs externas em nossos testes e garantirmos que não teremos falhas intermitentes.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>api</category>
      <category>testing</category>
      <category>rspec</category>
    </item>
  </channel>
</rss>
