如何声明在 RSpec 中的示例之间共享的变量? [英] How to declare a variable shared between examples in RSpec?

查看:39
本文介绍了如何声明在 RSpec 中的示例之间共享的变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下规格:

...
describe Thing do

  it 'can read data' do
     @data = get_data_from_file  # [ '42', '36' ]
     expect(@data.count).to eq 2
  end

  it 'can process data' do
     expect(@data[0].to_i).to eq 42  # Fails because @data is nil
  end

end
...

我想要的只是在给定的describe上下文 中共享一个变量.我会在一个示例中写入一个值并在另一个示例中读取它.我该怎么做?

All I wanted is to have a variable shared in the given describe or context. I would write a value in one example and read it in another. How do I do that?

推荐答案

你应该使用 before(:each)before(:all) 块:

You should use before(:each) or before(:all) block:

describe Thing do
  before(:each) do
    @data = get_data_from_file  # [ '42', '36' ]
  end

  it 'can read data' do
    expect(@data.count).to eq 2
  end

  it 'can process data' do
    expect(@data[0].to_i).to eq 42
  end
end

区别在于 before(:each) 将针对每个 case 单独执行,并且 before(:all) 在此 describe/中的所有示例之前执行一次上下文.我建议您更喜欢 before(:each) 而不是 before(:all),因为在这种情况下每个示例都将被隔离,这是一个很好的做法.

The difference is that before(:each) will be executed for each case separately and before(:all) once before all examples in this describe/context. I would recommend you to prefer before(:each) over before(:all), because each example will be isolated in this case which is a good practice.

在极少数情况下您想使用 before(:all),例如,如果您的 get_data_from_file 执行时间很长,在这种情况下,您可以当然,为了速度而牺牲测试隔离.但我想告诉你,当使用 before(:all) 时,在一个测试中修改你的 @data 变量(it 块)将导致 describe/context 范围内的其他测试出现意外后果,因为它们会共享它.

There are rare cases when you want to use before(:all), for example if your get_data_from_file has a long execution time, in this case you can, of course, sacrifice tests isolation in favor of speed. But I want to aware you, that when using before(:all), modification of your @data variable in one test(it block) will lead to unexpected consequences for other tests in describe/context scope because they will share it.

before(:all) 例子:

describe MyClass do
  before(:all) do
    @a = []
  end

  it { @a << 1; p @a }
  it { @a << 2; p @a }
  it { @a << 3; p @a }
end

将输出:

[1]
[1, 2]
[1, 2, 3]

更新

回答你的问题

describe MyClass do
  before(:all) do
    @a = []
  end

  it { @a = [1]; p @a }
  it { p @a }
end

会输出

[1]
[]

因为在第一个 it 中,您在本地分配实例变量 @a,所以它与 before(:all) 块中的 @a 不同,也不是对其他 it 块可见,您可以通过输出 object_id 来检查它.所以只有修改才能奏效,赋值会导致新对象的创建.

Because in first it you are locally assigning instance variable @a, so it isn't same with @a in before(:all) block and isn't visible to other it blocks, you can check it, by outputting object_ids. So only modification will do the trick, assignment will cause new object creation.

因此,如果您多次分配变量,您可能最终会得到一个 it 块和多个期望.根据最佳实践,这是可以接受的.

So if you are assigning variable multiple times you should probably end up with one it block and multiple expectation in it. It is acceptable, according to best practices.

这篇关于如何声明在 RSpec 中的示例之间共享的变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆