web-dev-qa-db-fra.com

Accès aux variables d'instance de contrôleur à partir d'une spécification de contrôleur rspec

Ne devrais-je pas être en mesure de voir les variables d'instance qui sont créées dans une action de contrôleur à partir de mes tests rspect?

# /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
...

Voici la sortie que j'obtiens lorsque j'exécute cette spécification:

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

Ai-je tort de penser que je devrais avoir accès à @widget dans mes spécifications de contrôleur?

21
RobertJoseph

Utilisez la méthode assigns ( * note : assigns est maintenant obsolète. Voir le bas de ma réponse pour info):

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

Bien sûr, vous pouvez inspecter widget comme vous le souhaitez, mais sans voir ce que @widget provient de votre code de contrôleur fourni, je viens de vérifier si c'était nil

Si vous voulez puts le widget, comme dans votre exemple, imprimez-le simplement avec assigns

puts assigns(:widget)

EDIT: assigns est désormais obsolète (voir: https://apidock.com/Rails/ActionController/TestProcess/ assigne )

Si vous souhaitez continuer à utiliser assigns, vous devrez installer la gemme Rails-controller-testing .

Sinon, vous pourriez utiliser ce que Rails-controller-testing gem utilise en interne: @controller.view_assigns[]

27
Wes Foster

Dans Rails 5, assigns a maintenant été divisé en un nouveau Rails-controller-testing bijou.

Vous pouvez soit installer la gemme pour continuer à utiliser assigns, soit utiliser ce que le Rails-controller-testing gem utilise en interne, qui@controller.view_assigns[].

11
Will Clarke

# assigns est déconseillé. Voici une solution qui évite de tirer dans la gemme Rails-controller-testing

Bien qu'il puisse s'agir d'un odeur de code pour tester les variables d'instance dans les contrôleurs, pour mettre à niveau des applications plus anciennes, vous pouvez utiliser # instance_variable_get .

Exemple Rspec: expect(@controller.instance_variable_get(:@person).id).to eq(person_id)

10
stevepentler