web-dev-qa-db-fra.com

Rspec: Comment affecter une variable d'instance dans la spécification du contrôleur

class TestController < AplicationController
  #....

  private

  def some_method
    unless @my_variable.nil?
      #...
      return true
    end
  end
end

Je veux tester some_method directement dans les spécifications du contrôleur:

require 'spec_helper'

describe TestController do
  it "test some_method"
    phone = Phone.new(...)
    controller.assign(:my_variable,phone) #does not work
    controller.send(:some_method).should be_true
  end
end

Comment puis-je définir la variable d'instance TestController@my_variable à partir des spécifications du contrôleur?

39
ole

Lorsque je teste des méthodes privées dans des contrôleurs, plutôt que d'utiliser send, j'ai tendance à utiliser un contrôleur anonyme parce que je ne souhaite pas appeler directement la méthode privée, mais l'interface à la méthode privée (ou, dans le test ci-dessous, efficacement). écraser cette interface). Donc, dans votre cas, peut-être quelque chose comme: 

require 'spec_helper'

describe TestController do
  controller do
    def test_some_method
      some_method
    end
  end

  describe "a phone test with some_method" do

    subject { controller.test_some_method }

    context "when my_variable is not nil" do
      before { controller.instance_variable_set(:@my_variable, Phone.new(...)) }
      it { should be_true }
    end

    context "when my_variable is nil" do
      before { controller.instance_variable_set(:@my_variable, nil) } 
      it { should_not be_true } # or should be_false or whatever
    end     
  end
end

Il y a de bonnes discussions sur la question du test direct des méthodes privées dans ce Q & A de StackOverflow , qui m'a amené à utiliser des contrôleurs anonymes, mais votre opinion peut différer.

59
Paul Fioravanti

Je ne pense pas que vous souhaitiez accéder à une variable d'instance à partir de votre contrôleur de spécification, car celle-ci devrait tester le comportement, mais vous pouvez toujours stub la méthode private . Dans votre cas, cela devrait ressembler à ceci ça n'a pas tellement de sens):

describe TestController do
  it "test some_method"
    phone = Phone.new(...)
    controller.stub(:some_method).and_return(true)
    controller.send(:some_method).should be_true
  end
end

Si ce n'est pas ce que vous cherchez, jetez un coup d'œil à ceci: Comment définir une variable d'instance privée utilisée dans un test de méthode?

2
Alex Falke

instance_eval est un moyen relativement propre d'accomplir ceci:

describe TestController do
  it "test some_method" do
    phone = Phone.new(...)
    controller.instance_eval do
      @my_variable = phone
    end
    controller.send(:some_method).should be_true
  end
end

Dans ce cas, utiliser do...end sur instance_eval est excessif, et ces trois lignes peuvent être réduites à:

controller.instance_eval {@my_variable = phone}
0
ReWrite