Accessing controller instance variables from within an rspec controller spec

RobertJoseph picture RobertJoseph · Sep 17, 2015 · Viewed 15.1k times · Source

Shouldn't I be able to see instance variables which are created in a controller action from within my rspect tests?

# /app/controllers/widget_controller.rb
...
def show
  @widget = ...
  puts "in controller: #{@widget}"
end
...

--

# /spec/controllers/widget_controller_spec.rb
RSpec.describe WidgetController, type: :controller do
...
describe "GET #show" do
  it "assigns the requested widget as @widget" do
    get :show, { :id => 1 } # this is just an example - I'm not hardcoding the id

    puts "in spec: #{@widget}"
  end
end
...

Here is the output I get when I run that spec:

controller: #<Widget:0x007f9d02aff090>
in spec:

Am I wrong in thinking that I should have access to @widget in my controller spec?

Answer

Wes Foster picture Wes Foster · Sep 17, 2015

Use the assigns method (*note: assigns is now deprecated. See bottom of my answer for info):

it "assigns the @widget"
  expect(assigns(:widget)).not_to be_nil
end

Of course, you can inspect widget as you'd like, but without seeing what @widget is from your provided controller code, I just checked if it was nil

If you're wanting to puts the widget, like in your example, just print it with assigns

puts assigns(:widget)

EDIT: assigns is now deprecated (see: https://apidock.com/rails/ActionController/TestProcess/assigns)

If you want to continue using assigns you will need to install the rails-controller-testing gem.

Otherwise, you could use what rails-controller-testing gem uses internally: @controller.view_assigns[]