DEV Community

Isadora Rocha
Isadora Rocha

Posted on

1

REspec Estrutura de Teste em Ruby on Rails

Considere a aplicação já criada

  • Nosso model é Article, com os atributos title(string) e content(text)

⇾ Utilizando rails c no terminal

Criaremos um array de hashes utilizando rails c para um teste rápido

blog(dev)* articles = [
blog(dev)*   {title: 'art 1', content: 'conteudo do art 1'},
blog(dev)*   {title: 'art 2', content: 'conteudo do art 2'},
blog(dev)*   {title: 'art 3', content: 'conteudo do art 3'}
blog(dev)> ]
Enter fullscreen mode Exit fullscreen mode

⇾ Utilizando arquivo seeds.rb

O arquivo seeds.rb é usado para configurar um ambiente de desenvolvimento ou teste com dados de exemplo, ou para fornecer dados iniciais ao banco de dados de produção. Ao executar o comando rails db:seed, ele rodará o arquivo e insere os dados no banco de dados.

No caso, o uso do rails c, os dados são imediatamente criados no banco de dados, mas essa ação não fica registrada em nenhum arquivo. Portanto, é adequado para testes rápidos ou manipulações de dados interativas que você não precisa necessariamente registrar para uso futuro.

Agora, deve-se colocar o mesmo array de hashes dentro do arquivo seeds.rbpara ficar registrado.

Image description

E, por fim, executar Article.create(articles) no rails c.


⇾ Agora, vamos ao controller

  1. Criar uma pasta, dentro da pasta controllers, chamada api. Logo após, criar outra pasta chamada v1.
    É uma boa prática para não deixar tudo junto na aplicação.

  2. Agora, no arquivo articles_controller.rb, devemos alterar a class ArticlesController < AplicattionController para:

class Api::V1::ArticlesController < ActionController::API
Enter fullscreen mode Exit fullscreen mode
  1. Dentro do método index, adicionar um render json - um retorno para a requisição GET da aplicação.
def index
    render json: { message: 'carregado'}
end
Enter fullscreen mode Exit fullscreen mode

CÓDIGO COMPLETO

class Api::V1::ArticlesController < ActionController::API
  def index
    Article.all
    render json: { message: 'carregado'}
  end
end
Enter fullscreen mode Exit fullscreen mode

GET 127.0.0.1:3000/articles no POSTMAN.
Image description

OBS.: talvez tenha ocorrido um erro, deve-se configurar as rotas no arquivo routes.rb.

resources :articles, only: :index
Enter fullscreen mode Exit fullscreen mode

⇾ Agora, vamos ao routes

Como não iremos utilizar as views, precisamos especificar um formato obrigatório (constraints), no caso utilizaremos json e xml, como exemplo.

Em config > routes.rb, vamos precisar definir namespaces e constraints.

namespace :api, constraints: ->(req) { %w[json].include? req.format } do
    namespace :v1 do
      resources :articles, only: :index
    end
  end
Enter fullscreen mode Exit fullscreen mode
  • O constraints ficará na mesma linha do no namespace :api para que todas as rotas dentro dessa pasta sigam a mesma regra.

⇾ GEMFILE
Dentro do group :development do end, adicionar a gem do RSpec

# Testes - [https://github.com/rspec/rspec-rails]
  gem 'rspec-rails', '~> 7.0.0'
Enter fullscreen mode Exit fullscreen mode

Em seguida, no terminal rodar bundle install para atualizar a gem. E por fim, executar rails g rspec:install.


⇾ SPEC
Dentro da pasta spec
, criaremos uma pasta chamada request, e dentro dessa pasta, criaremos um arquivo chamada: articles_spec.rb.

require 'rails_helper'
Enter fullscreen mode Exit fullscreen mode

Importar o arquivo rails_helper.rb, carrega o ambiente de teste e configurações necessárias para rodar os testes.

RSpec.describe 'Articles' do
end
Enter fullscreen mode Exit fullscreen mode

Definir um grupo de testes para a entidade Articles.
RSpec.describe é a forma de agrupar e descrever testes em RSpec.

before(:each) { Article.create(title: 'art 2', content: 'conteudo do art 2') }
Enter fullscreen mode Exit fullscreen mode

Criar um article com o título 'art 2' e o content 'conteúdo do art 2' antes de cada teste ser executado.

  • *Por quê?: * garantir que cada teste dentro desse grupo comece com um estado consistente, com pelo menos um artigo salvo no banco de dados.
require 'rails_helper'

RSpec.describe 'Articles' do
  before(:each) { Article.create(title: 'art 2', content: 'conteudo do art 2') }

(você está aqui)
  context "GET api/v1/articles" do

  end
end
Enter fullscreen mode Exit fullscreen mode

Dentro do bloco RSpec.describe, adicionar o bloco context "GET api/v1/articles" do end

Serve para agrupar testes relacionados à rota **GET api/v1/articles**. contexté usado para organizar os testes em torno de um cenário ou contexto específico.

Agora, adicionaremos outro bloco **it 'responds with status Ok' do end**

...
context "GET api/v1/articles" do
(você está aqui)
    it 'responds with status Ok' do

    end
  end
Enter fullscreen mode Exit fullscreen mode

Esse bloco define um teste individual. Dentro do bloco it é uma descrição do que o teste deve verificar, neste caso, se a resposta da rota GET api/v1/articles.json retorna um status Ok (200).

Dentro do bloco it, deve adicionar essas duas linhas:

context "GET api/v1/articles" do
    it 'responds with status Ok' do
(você está aqui)
      get '/api/v1/articles.json'
      expect(response).to have_http_status(:ok)
    end
Enter fullscreen mode Exit fullscreen mode

O get '/api/v1/articles.json', faz uma requisição HTTP GET para a rota /api/v1/articles.json.. Esse método simula uma chamada à API.

O expect(response).to have_http_status(:ok), verifica se a resposta da requisição tem o status :ok (200). Se a API responder com um status diferente, o teste falhará.

Por fim, adicionar mais um bloco it (não é dentro do bloco it anterior).

...
it 'responds with correct persistes article json' do
      get '/api/v1/articles.json'
      expect(response.body).to include('art 2')
      expect(response.body).to include('conteudo do art 2')
end
Enter fullscreen mode Exit fullscreen mode

O it 'responds with correct persisted article json' do, define outro teste individual, que verifica se o JSON retornado pela API contém os dados do artigo que foi criado no before.

O expect(response.body).to include('art 2'), verifica se o corpo da resposta (response.body) inclui o título 'art 2'.

*⇾ CÓDIGO COMPLETO *

require 'rails_helper'

RSpec.describe 'Articles' do
  before(:each) { Article.create(title: 'art 2', content: 'conteudo do art 2') }

  context "GET api/v1/articles" do
    it 'responds with status Ok' do
      get '/api/v1/articles.json'
      expect(response).to have_http_status(:ok)
    end

    it 'responds with correct persistes article json' do
      get '/api/v1/articles.json'
      expect(response.body).to include('art 2')
      expect(response.body).to include('conteudo do art 2')
    end
  end
end

Enter fullscreen mode Exit fullscreen mode

RETORNANDO AO CONTROLLER
Ao invés de:

class Api::V1::ArticlesController < ActionController::API
  def index
    Article.all
    render json: { message: 'carregado'}
  end
end
Enter fullscreen mode Exit fullscreen mode

Vamos alterar para que a API retorne todos os dados, e que seja status OK.

class Api::V1::ArticlesController < ActionController::API
  def index
    render json: Article.all, status: :ok
  end
end
Enter fullscreen mode Exit fullscreen mode

⇾ Para testar o RSpec
No terminal, executar rspec

➜  blog git:(main) ✗ rspec
.

Finished in 0.05506 seconds (files took 2.19 seconds to load)
1 example, 0 failures

➜  blog git:(main) ✗ 
Enter fullscreen mode Exit fullscreen mode

Essa mensagem indica que ocorreu tudo correto.


*⇾ Para testar no Postman *
Como definimos como json e xml, as rotas devem ser:

  • GET 127.0.0.1:3000/articles.json ou,
  • GET 127.0.0.1:3000/articles.xml

É isso. Obrigada!

REFERÊNCIAS:
Api app/Rails (Rails Guides): https://guides.rubyonrails.org/api_app.html
Routing/Rotas (Rails Guides): https://guides.rubyonrails.org/routing.html
RSpec Rails: https://github.com/rspec/rspec-rails
Rails Status codes: http://www.railsstatuscodes.com/
**Action Controller API: **https://api.rubyonrails.org/classes/ActionController/API.html
**Introdução a Api com Rails - primeiros passos: **https://www.youtube.com/watch?v=cj3GIO2CETo

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay