#rspec
#rspec
Вопрос:
Я использую Rspec 2.0. Я не понимаю, как здесь работает область видимости… Каким-то образом вы можете прочитать переменную в любом блоке, но я не могу ее обновить? почему это?
describe 'Test App' do
before(:all) do
@test= :blah
end
it 'test' do
@test=:bye
p @test # => prints bye
end
it 'test' do
p @test # => prints blah rather than bye...
end
end
Комментарии:
1. Сегодня вечером нашел эту статью, в которой рассматриваются особенности того, как экземпляр, класс и глобальные переменные отслеживаются в наших тестах. brentlavelle.wordpress.com/2011/04/04 /…
Ответ №1:
Согласно книге RSpec, before(:all)
:
… запускается один и только один раз в своем собственном экземпляре Object, но переменные его экземпляра копируются в каждый экземпляр, в котором выполняются примеры. Предостережение при использовании этого: в общем, мы хотим, чтобы каждый пример выполнялся в полной изоляции друг от друга. Как только мы начинаем делиться состоянием между примерами, начинают происходить неожиданные вещи.
Таким образом, в ваших примерах @blah
копируется перед запуском каждого теста, поэтому присвоенные ему значения не переносятся из одного примера в другой.
Похоже, вы хотите сделать что-то вроде этого (воздушный код):
it "gets a token" do
@token = OAuth.some_method_that_returns_a_token
end
it "uses that token to access some OAuth feature" do
result = OAuth.some_feature(@token)
result.should be_something_something
end
Это попахивает проверкой OAuth, а не вашего кода. Вам следует рассмотреть возможность отключения some_feature
метода (больше кода air):
it "responds in some way when I use a valid token" do
@token = mock('token')
OAuth.should_receive(:some_feature).with(@token).and_return("success")
result = my_code_which_uses_ouath(@token)
result.should == "success"
end
Ответ №2:
На самом деле все это свойство ruby, а не сам RSpec. Блок before — это обратный вызов, вызываемый перед выполнением каждого it-блока. Так вот как создается экземпляр вашей переменной blah
. Когда в вашем втором тесте вы определили, что это будет bye, это определение переопределяется, когда блок before снова вызывается для следующего теста.
Комментарии:
1. Итак, как вы относитесь к ее повторному использованию? Это before (все), поэтому оно должно быть вызвано только один раз на самом деле в этом описании… не a перед каждым
Ответ №3:
Я столкнулся с той же проблемой и решил ее с помощью хэша, в котором я меняю значения:
describe "carry over value" do
let (:global) { Hash.new }
before :all do
global[:var1] = "foo"
end
it "should be foo" do
global[:var1].should == "foo"
end
it "set to bar" do
global[:var1] = "bar"
global[:var1].should == "bar"
end
it "should still be bar" do
global[:var1].should == "bar"
end
end