开发者

Issue with Instance variable and Rspec 2.x

开发者 https://www.devze.com 2023-02-28 04:53 出处:网络
I am using Rspec 2.0.I am not understanding how the scope works h开发者_JAVA百科ere... Somehow you can read the variable in any block but I cannot update it? why is that?

I am using Rspec 2.0. I am not understanding how the scope works h开发者_JAVA百科ere... Somehow you can read the variable in any block but I cannot update it? why is that?

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


According to the RSpec book, before(:all):

... gets run once and only once in its own instance of Object, but its instance variables get copied to each instance in which the examples are run. A word of caution in using this: in general, we want to have each example run in complete isolation from one another. As soon as we start sharing state across examples, unexpected things begin to happen.

So in your examples @blah is copied before each test is run, thus values assigned to it do not carry over from one example to another.

It seems like you want to do something like this (air code):

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

This smells like a test of OAuth, not of your code. You should consider stubbing out the some_feature method (more air code):

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


This is really all a property of ruby and not RSpec itself. The before block is a callback invoked before each it block is executed. So that is how your variable is instantiated to blah. When in your second test your defined it to be bye that definition is redefined when the before block is invoked again for the next test.


I run into the same problem and solved it with Hash in which I change values:

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
0

精彩评论

暂无评论...
验证码 换一张
取 消