RSpec的怎么让啊让啊!替换原来的参数?

How do RSpec's let and let! replace the original parameters?

在Rspec写测试的过程中,如果遇到重复的必填参数{...},可以用let来写。这样就避免了每个例子都提前写一堆参数准备。

但是,我不太了解 Better Specs 的范式。他的原代码是这样的:

describe '#type_id' do
  before { @resource = FactoryBot.create :device }
  before { @type     = Type.find @resource.type_id }

  it 'sets the type_id field' do
    expect(@resource.type_id).to eq(@type.id)
  end
end

使用let后变成如下

describe '#type_id' do
  let(:resource) { FactoryBot.create :device }
  let(:type)     { Type.find resource.type_id }

  it 'sets the type_id field' do
    expect(resource.type_id).to eq(type.id)
  end
end

看起来调用a resource 的方式几乎相同,使用 let 有什么好处? FactoryBot.create:device的作用是什么?而且我看不到 type 在哪里被调用?

不同之处在于 let 被延迟计算,然后为规范的其余部分记忆。

因此在第一个示例中,首先是 before 块 运行 并设置 @resource 和 @type 的值,然后是规范 运行s.

在第二个例子中,规范 运行s 和当它引用 'resource' let 块 运行s 和 returns 一个值,然后当 'type' 被引用的是 运行s 的 let 块。类型本身的 let 块引用 'resource' 因此它获取从第一次引用资源时记忆的资源值。

对于它的价值,我不同意让我们 'better'。我和我的团队发现,他们所做的只是让规范更难理解,而获益甚微,我们已经在所有项目中删除了对它们的所有使用。

事实上,我认为 'better specs' 中的大部分实际上都是糟糕的建议,所以如果您正在努力理解为什么某些东西是 'better',那么您并不孤单 :)