kri*_*sna 87 unit-testing rspec ruby-on-rails
RSpec let与before块之间的区别是什么?
什么时候使用?
下面的例子中有什么好方法(让或之前)?
let(:user) { User.make !}
let(:account) {user.account.make!}
before(:each) do
@user = User.make!
@account = @user.account.make!
end
Run Code Online (Sandbox Code Playgroud)
我研究过这个stackoverflow帖子
但是为上面的关联内容定义let是否合适?
Jay*_*Jay 137
人们似乎已经解释了一些在他们不同的基本途径,但冷落before(:all)和不完全解释为什么他们应该被使用.
这是我的信念,实例变量在绝大多数规格的没有使用的地方,部分原因是由于提到的原因这个答案,所以我不会提到他们作为一个不错的选择.
让块
let块中的代码仅在引用时执行,延迟加载这意味着这些块的排序无关紧要.这为您提供了大量的功能,可以通过您的规格减少重复设置.
一个(非常小而且做作)的例子是:
let(:person) { build(:person) }
subject(:result) { Library.calculate_awesome(person, has_moustache) }
context 'with a moustache' do
let(:has_moustache) { true }
its(:awesome?) { should be_true }
end
context 'without a moustache' do
let(:has_moustache) { false }
its(:awesome?) { should be_false }
end
Run Code Online (Sandbox Code Playgroud)
您可以看到has_moustache在每种情况下都有不同的定义,但不需要重复subject定义.需要注意的一点是,let将使用当前上下文中定义的最后一个块.这适用于设置大多数规范使用的默认值,如果需要可以覆盖.
例如,检查calculate_awesomeif 的返回值是否传递了一个设置为true 的person模型top_hat,但没有胡子:
context 'without a moustache but with a top hat' do
let(:has_moustache) { false }
let(:person) { build(:person, top_hat: true) }
its(:awesome?) { should be_true }
end
Run Code Online (Sandbox Code Playgroud)
关于let块的另一个注意事项是,如果你正在搜索保存到数据库中的东西(即Library.find_awesome_people(search_criteria)),它们不应该被使用,因为它们不会被保存到数据库,除非它们已被引用.let!或before块是这里应该使用的.
此外,从来没有过使用before触发的执行let块,这是let!用于制造!
让!块
let!块按照它们的定义顺序执行(很像前一个块).与块之前的一个核心差异是,您获得了对此变量的显式引用,而不是需要回退到实例变量.
与let块一样,如果let!使用相同的名称定义多个块,则最新的块将用于执行.核心区别在于let!如果像这样使用块将被执行多次,而let块将仅执行最后一次.
之前(:每个)阻止
before(:each)是块之前的默认值,因此可以引用,before {}而不是before(:each) {}每次都指定完整.
我个人倾向于before在几种核心情况下使用块.如果出现以下情况,我将使用块
before { get :index }).即使您可以subject在很多情况下使用它,但如果您不需要引用,有时会感觉更明确.如果您发现自己before为规范编写大块,请检查您的工厂并确保您完全了解特征及其灵活性.
之前(:所有)块
这些只在当前上下文(及其子代)中的规范之前执行过一次.如果正确编写,这些可以非常有用,因为在某些情况下这可以减少执行和工作量.
一个例子(根本不会影响执行时间)是为测试模拟一个ENV变量,你应该只需要做一次.
希望有帮助:)
Spy*_*ros 25
几乎总是,我更喜欢let.您链接的帖子指定let也更快.但是,有时,当必须执行许多命令时,我可以使用,before(:each)因为当涉及许多命令时,它的语法更清晰.
在你的例子中,我肯定更愿意使用let而不是before(:each).一般来说,当只进行一些变量初始化时,我倾向于使用let.
mik*_*ber 15
没有提到的一个很大的区别是,定义的变量let在第一次调用之前不会被实例化.因此,虽然before(:each)块将实例化所有变量,但是let您可以定义多个可能在多个测试中使用的变量,但它不会自动实例化它们.如果您希望预先加载所有数据,那么在不知道这一点的情况下,您的测试可能会回过头来咬自己.在某些情况下,您甚至可能希望定义许多let变量,然后使用before(:each)块来调用每个let实例,以确保数据可用.
| 归档时间: |
|
| 查看次数: |
26534 次 |
| 最近记录: |