Suponha que temos um CartController e uma especificação correspondente. No momento, apenas usuários logados podem adicionar itens a seus carrinhos, e queremos oferecer suporte a carrinhos para usuários convidados.
Até agora, a especificação pode ser assim:
describe CartController do
let(:user) { create(:user) }
let(:item) { create(:item) }
let(:response_items) { JSON.parse(response["items"]) }
describe :index do
it "returns items in the cart" do
user.cart.add(item)
get :index
response_items[0]["id"].should == item.id
end
end
describe :create do
it "adds an item to the cart" do
post :create, id: item.id
response_items[0]["id"].should == item.id
end
end
describe :destroy do
it "removes an item from the cart" do
user.cart.add(item)
delete :destroy, id: item.id
response_items.should be_empty
end
end
end
Agora, para adicionar suporte para carrinhos de convidados, pode ser tentador adicionar coisas como:
it "adds an item to the cart when user is a guest"
it "removes an item to the cart when user is a guest"
Mas isso vai acabar repetindo muitas das especificações anteriores. É importante isolar o que está realmente mudando, que é o usuário. Então, vamos configurar alguns blocos de contexto para os dois cenários:
context "signed in user" do
let(:user) { create(:user) }
end
context "guest user" do
let(:user) { User.new }
end
Agora, precisamos apenas de nossas especificações anteriores para executar nesses dois contextos. Podemos fazer isso movendo-os para exemplos compartilhados e executando esses exemplos em nossos contextos:
shared_examples "cart requests" do
describe :index
describe :create
describe :destroy
end
context "signed in user" do
let(:user) { create(:user) }
it_behaves_like "cart requests"
end
context "guest user" do
let(:user) { User.new }
it_behaves_like "cart requests"
end
Com essa abordagem, adicionamos uma nova camada de comportamento às nossas especificações com muito pouca repetição ou código real.
E o mais importante, como reutilizamos as especificações anteriores, podemos ter certeza de que todas as funcionalidades de um usuário real também estão disponíveis para usuários convidados.