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
из спецификации контроллера?
Ответы
Ответ 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}