实例变量和 Rspec 2.x 的问题

发布于 2024-11-02 16:33:28 字数 316 浏览 0 评论 0原文

我正在使用 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

I am using Rspec 2.0. I am not understanding how the scope works here... 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

又怨 2024-11-09 16:33:28

根据RSpec 书before(:all)

...在其内部运行一次且仅一次
自己的对象实例,但它
实例变量被复制到每个
实例中的例子是
跑步。使用此功能时请注意:
一般来说,我们希望每个
示例完全隔离运行
彼此。一旦我们开始
跨示例共享状态,
意想不到的事情开始发生。

因此,在您的示例中,在运行每个测试之前都会复制 @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

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
傲世九天 2024-11-09 16:33:28

这实际上是 ruby​​ 的所有属性,而不是 RSpec 本身。 before 块是在执行每个 it 块之前调用的回调。这就是你的变量被实例化为blah的方式。当您在第二个测试中将其定义为再见时,当下一个测试再次调用 before 块时,该定义将被重新定义。

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.

离不开的别离 2024-11-09 16:33:28

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

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文