Instance变量和Rspec 2.x的问题

时间:2011-04-22 03:54:41

标签: 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

3 个答案:

答案 0 :(得分:2)

根据the RSpec bookbefore(: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方法(更多航空代码):

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

答案 1 :(得分:1)

这真的是红宝石的所有属性,而不是RSpec本身。 before块是在执行每个块之前调用的回调。这就是你的变量被实例化为blah的方式。在第二次测试时,您将其定义为再次定义,以便在下一次测试再次调用before块时重新定义。

答案 2 :(得分:0)

我遇到了同样的问题并用Hash解决了它,我在其中更改了值:

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