为什么在RSpec测试中有时会过度使用实例变量?

时间:2016-03-09 11:41:55

标签: ruby-on-rails ruby testing rspec rspec-rails

我已经注意到RSpec单元测试等实例变量用法的例子。

这样的事情:

it 'should update something' do
  @user = user(:userone)
  @attr = {
    :name => 'this',
    :phone => 'that'
  }
  put :update, :id => @user.id, :user => @attr

  @user.reload
  expect(response.status).to eq(200)
  expect(@user.name).to eq('this')
  expect(@user.phone).to eq('that')
end

如果不在before :each等范围内设置变量,为什么不使用局部变量?

1 个答案:

答案 0 :(得分:3)

总体问题是测试中的变量(如任何程序中的变量)应该具有最小范围。这使得读者更容易理解测试,因为它最大限度地减少了他们必须考虑的代码量,并且通常允许运行时更高效。因此,如果一个实例变量(或者,在当前的RSpec中,let变量)可以是本地变量(没有重复代码或失去效率),那么它应该是。

当从before块传递数据到示例(it块)的最佳可用方法是在实例变量中时,我常常看到类似于您的示例的规范。有时它们是由经验不足的程序员编写的,他们在规范中看到了很多实例变量并且不加思索地模仿了这些变量。 (我仍然在Rails控制器中看到相同的错误。)有时它们是由于某人内嵌了一个前块但没有麻烦地将不再需要实例变量的实例变量更改为本地变量。

这些天RSpec提供letlet比实例变量更好的一个原因是使用let变量看起来像本地人,因此如果将本地变为let变量,则无需更改它们或相反亦然。但是,我仍然经常看到测试数据的问题,该问题仅在一个示例中使用,在let变量中可以并且应该只是本地变量。就像过度使用实例变量一样,这有时来自没有经验的程序员不假思索地模仿的例子,有时来自于在测试更改后无法清理,导致let变量不必要。