+-----------------------------------------------------------------------------------------+
+----------+ +------------------+
| | | |
| View | | |
| Specs | View | |
| | | |
+----------+ | |
| |
+--------------------------------------------------------------------+ +-+
| |
| |
Route | |
| |
| |
+---------------------------------------------------------------------+ +-+
| |
+-------------+ | |
| | | |
| Helper | | Features |
| Specs | Helper +-------------------+ | Specs |
| | | | | |
+-------------+ | | | |
| | | |
+---------------------------------------+ +---------+ +-+
| | | |
| | | |
Controller | Controller | | |
| Specs | | |
| | | |
| | | |
+---------------------------------------+ +---------+ +-+
| | | |
+------------+ | | | |
| | +-------------------+ | |
| Model | Model | |
| Specs | | |
| | | |
+------------+ +------------------+
+-------------------------------------------------------------------------------------------+
example:
#spec/models/car_spec.rb
RSpec.describe Car, '#available?' do
it 'returns true if it's available' do
car = build(:car, available: true)
expect(car.available?).to eq true
end
end
Documentation: Relishapp view-specs
Note: With devise, do not forget to add following lines on your rails_helper.rb
config.include Devise::TestHelpers, type: :controller
config.include Devise::TestHelpers, type: :view
assign: used to assign an instance variable which can be called in a view.
example: my view uses @cars
variable
assign(:cars, [
Car.create!(:name => "Civic"),
Car.create!(:name => "Clio")
])
render: try to render view related to assign variable example:
RSpec.describe "widgets/index" do
context "with 2 widgets" do
before(:each) do
assign(:cars, [
Car.create!(:name => "Civic"),
Car.create!(:name => "Clio")
])
end
it "displays both cars" do
render
expect(rendered).to match /Civic/
expect(rendered).to match /Clio/
end
end
end
You can also render a specifi template:
render template: 'cars/car.html.erb'
You can also render a partial template:
render partial: 'cars/car.html.erb', locals: {car: car}
How to stub a helper
require 'rails_helper'
RSpec.describe 'secrets/index' do
before do
allow(view).to receive(:admin?).and_return(true)
end
it 'checks for admin access' do
render
expect(rendered).to match /Secret admin area/
end
end
example:
# spec/views/car/_car.html.erb_spec.rb
require 'rails_helper'
RSpec.describe 'car/_car.html.erb' do
context 'if it has an image' do
it 'renders the image inline' do
car = build(:car, image_url: 'http://example.com/car.jpg')
render partial: 'car/car.html.erb', locals: { car: car }
expect(rendered).to have_selector "img[src='#{car.image_url}]"
end
end
end
Same example with a user session:
# spec/views/car/_car.html.erb_spec.rb
require 'rails_helper'
RSpec.describe 'car/_car.html.erb' do
context 'if it has an image' do
it 'renders the image inline' do
current_user = double('user')
allow(current_user).to receive(:cache_can_create?).and_return(true)
allow(view).to receive(:current_user).and_return(current_user)
car = build(:car, image_url: 'http://example.com/car.jpg')
render partial: 'car/car.html.erb', locals: { car: car }
expect(rendered).to have_selector "img[src='#{car.image_url}]"
end
end
end
documentation: https://www.relishapp.com/rspec/rspec-rails/docs/controller-specs
render_template
expect(response).to render_template(:new)
redirect_to
expect(response).to redirect_to(location)
have_http_status
expect(response).to have_http_status(:created)
example:
require 'rails_helper'
RSpec.describe CarsController, '#create' do
context 'When the program is invalid' do
it 're-renders the form' do
post :create, car: attributes_for(:car, :invalid)
expect(response).to render_template(:new)
end
end
end
Same example with a user session:
require 'rails_helper'
RSpec.describe CarsController, '#create' do
context 'When the program is invalid' do
it 're-renders the form' do
user = double('user')
allow(user).to receive(:can_create?).and_return(true)
allow(request.env['warden']).to receive(:authenticate!).and_return(user)
allow(controller).to receive(:current_user).and_return(user)
post :create, car: attributes_for(:car, :invalid)
expect(response).to render_template(:new)
end
end
end
Note:
- All the
allow
instructions have been used to stub devise authentication attributes_for
is a FactoryGirl method that returns a hash of attributes that can be used to build a Car instance
....