我注意到在 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
等中设置变量,为什么不直接使用局部变量?
总体问题是测试中的变量(就像任何程序中的变量一样)应该具有尽可能小的范围。这使读者更容易理解测试,因为它最大限度地减少了他们必须考虑的代码量,并且通常可以提高运行时的效率。因此,如果一个实例变量(或者,在当前的 RSpec 中,一个 let
变量)可以是本地的(不会重复代码或降低效率),它应该是。
当将数据从 before
block 传递到示例(it
block )的最佳可用方式是在实例变量中时,我曾经看到过这样的规范你的榜样一直。有时它们是由没有经验的程序员编写的,他们看到规范中使用了很多实例变量并且不假思索地模仿了它。 (我仍然在 Rails Controller 中看到同样的错误。)有时,它们是由于有人内联了一个 before block ,但没有费心将不再需要作为实例变量的实例变量更改为局部变量。
最近 RSpec 提供了 let
。 let
比实例变量更好的一个原因是 let
变量的使用看起来像局部变量,因此如果将局部变量更改为let
变量,反之亦然。然而,我仍然经常看到测试数据的问题,它只在一个示例中使用,而在 let
变量中定义它可以而且应该只是本地的。就像过度使用实例变量一样,这有时是由于缺乏经验的程序员不假思索地模仿示例,有时是由于测试更改后未能清理导致 let
变量变得不必要。