webentwicklung-frage-antwort-db.com.de

Rspec: Zuweisen von Instanzvariablen in Controller-Spezifikationen

class TestController < AplicationController
  #....

  private

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

Ich möchte Test some_method direkt in der Controller-Spezifikation:

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

Wie kann ich TestController Instanzvariable @my_variable von Controller-Spezifikationen setzen

39
ole

Beim Testen privater Methoden in Controllern verwende ich eher send. Ich neige dazu, einen anonymen Controller zu verwenden, da ich nicht die private Methode direkt aufrufen möchte, sondern die Schnittstelle zur privaten Methode (oder im Test unten) , diese Schnittstelle effektiv stubben). Also in Ihrem Fall vielleicht so etwas wie: 

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

Es gibt einige gute Diskussionen über das direkte Testen von privaten Methoden in diese Fragen und Antworten zu StackOverflow , was mich dazu veranlasst hat, anonyme Controller zu verwenden, aber Ihre Meinung kann abweichen.

59
Paul Fioravanti

Ich glaube nicht, dass Sie von Ihrem Spec-Controller auf eine Instanzvariable zugreifen möchten, da die Spezifikation das Verhalten testen sollte, aber Sie können die private Methode immer stubben .. In Ihrem Fall sollte es so aussehen (in diesem Beispiel) es macht nicht so viel Sinn):

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

Wenn dies nicht das ist, wonach Sie suchen, schauen Sie sich das an: Wie setzt man die private Instanzvariable, die in einem Methodentest verwendet wird?

2
Alex Falke

instance_eval ist ein relativ sauberer Weg, um dies zu erreichen:

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

In diesem Fall ist die Verwendung von do...end auf instance_eval ein Overkill, und diese drei Zeilen können folgendermaßen verkürzt werden:

controller.instance_eval {@my_variable = phone}
0
ReWrite