Подтвердить что ты не робот

Rspec: как назначить переменную экземпляра в спецификации контроллера

class TestController < AplicationController
  #....

  private

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

Я хочу проверить some_method непосредственно в спецификации контроллера:

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

Как я могу установить переменную экземпляра TestController @my_variable из спецификации контроллера?

4b9b3361

Ответ 1

При тестировании частных методов в контроллерах вместо использования send я склонен использовать анонимный контроллер из-за того, что вы не хотите звонить частный метод напрямую, но интерфейс к частному методу (или, в приведенном ниже тесте, эффективно обманывает этот интерфейс). Итак, в вашем случае, возможно, что-то вроде:

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

Там было хорошее обсуждение проблемы прямого тестирования частных методов в этом StackOverflow Q & A, который поколебал меня на использование анонимных контроллеров, но ваше мнение может отличаться.

Ответ 2

Я не думаю, что вы хотите получить доступ к переменной экземпляра из вашего контроллера спецификации, поскольку спецификация должна проверять поведение, но вы всегда можете заглушить частный метод. В вашем случае это должно быть что-то вроде этого (в этом примере это не имеет особого смысла):

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

Если это не то, что вы ищете, посмотрите на это: Как установить переменную частного экземпляра, используемую в тесте метода?

Ответ 3

instance_eval - относительно чистый способ выполнить это:

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

В этом случае использование do...end на instance_eval является излишним, и эти три строки можно сократить до:

controller.instance_eval {@my_variable = phone}