Anteriormente, nós fizemos teste para model, agora vamos fazer teste para requests.
O que é o request e porque é importante testar ele.
Antes de nós testar, primeiramente, nós temos que entender o request, que traduzindo seria, requisição.
Você deve saber, eu espero, que a nossa internet funciona com base de requisição e resposta, ou seja, no meu navegador, eu estou requisitando uma página web para um servidor, e o servidor, por sua vez, vai me dar uma resposta sobre a requisição.
O servidor pode aceitar a requisição, pode negar ou até mesmo pode dar erro.
E é esse o nosso objetivo, nós queremos testar o que acontece quando faço requisição de formato HTML ou JSON, ou então quando acesso em uma página não autorizada, etc.
Então, para começar, vamos criar uma aplicação do começo para que vocês consigam me acompanhar.
A nossa ideia da aplicação é um simples blog, onde vai ter um controller e um model que é o post.
Se você quiser me acompanhar, basta executar os comandos abaixo para criar a aplicação.
rails new blog --skip-test
cd blog
echo 'gem "rspec-rails", group: [:development, :test]' >> Gemfile
echo 'gem "rails-controller-testing", group: :test' >> Gemfile
bundle install
rails g rspec:install
rails g resource Post titulo corpo:text
rails db:create db:migrate
Pronto com isso, estamos pronto para testar.
Testando
Beleza, para testar os requests não é tão difícil assim.
vamos escrever os testes
# spec/requests/posts_spec.rb
require 'rails_helper'
RSpec.describe "Posts", type: :request do
describe "GET posts" do
it "deve retornar sucesso" do
get posts_path
expect(response).to have_http_status(:success)
end
end
describe "GET post" do
it "deve retornar sucesso" do
post = Post.create(titulo: "Ólá", corpo: "bla bla bala")
get post_path(post)
expect(response).to have_http_status(:success)
end
it "deve ser redirecionado por não existir o post" do
get post_path("não existo")
expect(response).to have_http_status(:not_found)
end
end
describe "GET new post" do
it "deve retornar sucesso" do
get new_post_path
expect(response).to have_http_status(:success)
end
end
describe "Post posts" do
it "deve retornar created" do
post posts_path, params: {
post: {
titulo: "Reza a lenda",
corpo: "Ele está vindo"
}
}
expect(response).to redirect_to(post_path(assigns(:post)))
end
end
describe "GET edit post" do
it "deve retornar sucesso" do
post = Post.create(titulo: "Ólá", corpo: "bla bla bala")
get edit_post_path(post)
expect(response).to have_http_status(:success)
end
it "deve ser redirecionado por não existir o post" do
get edit_post_path("não existo")
expect(response).to have_http_status(:not_found)
end
end
describe "PUT post" do
it "deve retornar sucesso" do
post = Post.create(titulo: "Ólá", corpo: "bla bla bala")
put post_path(post), params: {
post: {
titulo: "sou eu o",
corpo: "tiririca"
}
}
expect(response).to redirect_to(post_path(assigns(:post)))
end
it "deve ser redirecionado por não existir o post" do
put post_path("não existo"), params: {
post: {
titulo: "sou eu o",
corpo: "tiririca"
}
}
expect(response).to have_http_status(:not_found)
end
end
describe "DELETE post" do
it "deve retornar sucesso" do
post = Post.create(titulo: "Ólá", corpo: "bla bla bala")
delete post_path(post)
expect(response).to have_http_status(:redirect)
end
it "deve ser redirecionado por não existir o post" do
delete post_path("não existo")
expect(response).to have_http_status(:not_found)
end
end
end
É meio grandinho, mas não tem muitas diferenças em teste de model, como nós fizemos antes.
Só vamos dar a atenção nesses métodos que vou citar.
get
post
put
delete
have_http_status
redirect_to
assigns
É só isso, porém existe mais métodos, como patch
etc, mas raramente você usa ele.
Os primeiros quatros métodos são, obviamente, métodos de requisição HTTP, se não sabe sobre isso, eu recomendo que estude isso, porque isso é bastante importante.
Não tem muito o que explicar sobre eles, pois o próprio nome diz o que eles fazem.
Então vamos para have_http_status
e redirect_to
.
O have_http_status
é um método para verificar se o argumento passado é equivalente ao "status code" da resposta do servidor.
Enquanto o redirect_to
é o método para verificar se o argumento passado é equivalente ao página que o servidor redirecionou.
Não tem muito segredo, se você entende de protocolo HTTP.
Agora nós temos o método assigns
, ele relaciona com a variável da instância, ou seja, vamos pegar o nosso caso, o argumento que eu passei foi :post
, isso seria o equivalente o @post
, isso é útil para caso em que você quer o id do post, que é o nosso caso, ou então saber que ele foi criado ou atualizado com sucesso.
Pronto, terminei com a explicação, agora vamos testar.
rspec
Finished in 0.4995 seconds (files took 4.57 seconds to load)
13 examples, 11 failures, 2 pending
Failed examples:
rspec ./spec/requests/posts_spec.rb:5 # Posts GET posts deve retornar sucesso
rspec ./spec/requests/posts_spec.rb:13 # Posts GET post deve retornar sucesso
rspec ./spec/requests/posts_spec.rb:20 # Posts GET post deve ser redirecionado por não existir o post
rspec ./spec/requests/posts_spec.rb:28 # Posts GET new post deve retornar sucesso
rspec ./spec/requests/posts_spec.rb:36 # Posts Post posts deve retornar created
rspec ./spec/requests/posts_spec.rb:49 # Posts GET edit post deve retornar sucesso
rspec ./spec/requests/posts_spec.rb:56 # Posts GET edit post deve ser redirecionado por não existir o post
rspec ./spec/requests/posts_spec.rb:64 # Posts PUT post deve retornar sucesso
rspec ./spec/requests/posts_spec.rb:76 # Posts PUT post deve ser redirecionado por não existir o post
rspec ./spec/requests/posts_spec.rb:89 # Posts DELETE post deve retornar sucesso
rspec ./spec/requests/posts_spec.rb:96 # Posts DELETE post deve ser redirecionado por não existir o post
Bem, nós esquecemos de criar as actions do controller e as views.
Vamos para app/controller/posts_controller.rb
e criar as actions.
# app/controller/posts_controller.rb
class PostsController < ApplicationController
before_action :define_post, except: [:index, :new, :create]
def index
@post = Post.all
end
def show
end
def new
end
def create
@post = Post.new
if @post.save
redirect_to post_path(@post)
else
render :new, status: :unprocessable_entity
end
end
def edit
end
def update
if @post.update post_params
redirect_to post_path(@post)
else
render :edit
end
end
def destroy
if @post.destroy
redirect_to posts_path
end
end
private
def post_params
params.require(:post).permit(:titulo, :corpo)
end
def define_post
begin
@post = Post.find(params[:id])
rescue ActiveRecord::RecordNotFound
redirect_to posts_path, status: :not_found
end
end
end
Pronto, criamos as actions, agora vamos criar as views, basta executar os comandos abaixo.
touch app/views/posts/index.html.erb app/views/posts/show.html.erb app/views/posts/new.html.erb app/views/posts/edit.html.erb
Agora sim, nós estamos pronto, vamos rodar o teste.
rspec
Finished in 0.81536 seconds (files took 4.77 seconds to load)
13 examples, 0 failures, 2 pending
Passou.
E é isso, terminamos aqui, só que não, eu estava pensando aqui, será que vale a pena fazer um teste para uma aplicação de API? Pois é útil aprender como que testa as requisições do tipo JSON.
Mas não vale a pena, porque seria um copiar e colar e colocar um argumento header e testar se resposta é json.
Eu só vou fazer só um teste de requisição para ter noção.
Vamos para spec/requests/post_spec.rb
.
# spec/requests/post_spec.rb
require 'rails_helper'
RSpec.describe "Posts", type: :request do
describe "GET posts" do
...
describe "requisição json" do
it "deve retornar sucesso" do
headers = { "ACCEPT": "application/json" }
get posts_path, headers: headers
expect(response.content_type).to eq("application/json; charset=utf-8")
expect(response).to have_http_status(:success)
end
end
end
...
end
Se nós analisamos o teste, vai perceber que não teve muita diferença o que a gente fez anteriormente, eu passei o argumento headers
no get
e testei se o tipo de conteúdo é JSON, só isso.
Se nós rodar o teste, é obvio que vai falhar, então para evitar isso, vamos para app/controller/post_controller.rb
.
class PostsController < ApplicationController
...
def index
@posts = Post.all
respond_to do |format|
format.html
format.json { render json: @posts }
end
end
...
end
Com isso, a nossa aplicação aceita a requisição HTML e JSON.
Agora, se nós rodar o teste, vai funcionar, e isso é o suficiente para nós testar a aplicação que atende requisição json.
Com isso, nós terminamos aqui.
Tchau!
Top comments (0)