Reputation: 6455
I have a new action which creates a circle and assigns the current parent as its administrator:
def new
return redirect_to(root_path) unless parent
@circle = Circle.new(administrator: parent)
end
I'm trying to test that the administrator ID is properly set, and have written out my test as such:
context 'with a parent signed in' do
before do
sign_in parent
allow(controller).to receive(:circle).and_return(circle)
allow(Circle).to receive(:new).and_return(circle)
end
it 'builds a new circle with the current parent as administrator' do
get :new
expect(@circle.administrator).to equal(parent)
end
end
This obviously throws an error as @circle
is nil
. How can I access the new object that hasn't yet been saved from my controller tests? I'm guessing it is some variety of allow / let but as I say all my searches have yielded nothing so far.
Upvotes: 0
Views: 4252
Reputation: 102433
You're approaching the problem wrong. Test the behavior of the controller. Not its implementation.
If this is a legacy application you can use assigns
to access the @circle
instance variable of the controller:
context 'with a parent signed in' do
before do
sign_in parent
end
it 'builds a new circle with the current parent as administrator' do
get :new
expect(assigns(:circle).administrator).to equal(parent)
end
end
But Rails 5 removes assigns
and using it is not encouraged in new projects.
Instead I would use a feature spec and actually test the steps of creating a circle:
require 'rails_helper'
RSpec.feature 'Circles' do
let(:parent) { create(:parent) }
context "a guest user" do
scenario "can not create circles" do
visit new_circle_path
expect(page).to have_content 'Please sign in'
end
end
context "when signed in" do
background do
login_as parent
end
scenario "can create circles" do
visit new_circle_path
fill_in 'name', with: 'Test Circle'
expect do
click_button 'Create circle'
end.to change(parent.circles, :count).by(+1)
expect(page).to have_content 'Test Circle'
end
end
end
Upvotes: 2
Reputation: 36110
You can use assigns
:
expect(assigns(:circle).administrator).to eq parent
However, note that with rails 5, this gets deprecated. The rational being that checking the assigned instance variables in controllers is too fragile and implementation specific.
The recommended alternative is either to test side effects (for example if this actually got persisted to the db) or do full feature tests.
Upvotes: 0