let
和RSpec中的before
块有什么区别?
什么时候使用每一种?
在下面的例子中,什么是好的方法(让或之前)?
let(:user) { User.make !}
let(:account) {user.account.make!}
before(:each) do
@user = User.make!
@account = @user.account.make!
end
我研究过这个
但是像上面这样定义let用于关联的东西好吗?
let
和RSpec中的before
块有什么区别?
什么时候使用每一种?
在下面的例子中,什么是好的方法(让或之前)?
let(:user) { User.make !}
let(:account) {user.account.make!}
before(:each) do
@user = User.make!
@account = @user.account.make!
end
我研究过这个
但是像上面这样定义let用于关联的东西好吗?
4条答案
按热度按时间gev0vcfq1#
人们似乎已经解释了它们之间的一些基本差异,但却忽略了
before(:all)
,也没有确切地解释为什么要使用它们。我相信,绝大多数规范中都没有示例变量的位置,部分原因是this answer中提到的原因,所以我不会在这里提到它们。
字母块
let
块中的代码只在被引用时执行,延迟加载意味着这些块的顺序是无关紧要的。这给了你很大的能力来减少通过你的规范重复设置。其中一个(非常小和人为的)例子是:
你可以看到
has_moustache
在每种情况下都有不同的定义,但是没有必要重复subject
的定义。需要注意的是,将使用当前上下文中定义的最后一个let
块。这对于设置大多数规范使用的默认值很有帮助,如果需要,可以覆盖它。例如,如果传递了
top_hat
设置为true但没有moustache的person
模型,则检查calculate_awesome
的返回值将为:关于let块的另一个需要注意的事情是,如果你要搜索已经保存到数据库的东西(例如
Library.find_awesome_people(search_criteria)
),不应该使用let块,因为除非已经引用过let块,否则let块不会保存到数据库中。let!
或before
块是这里应该使用的。此外,* 永远不要**使用
before
来触发let
块的执行,这就是let!
的用途!让!块
let!
块按照定义的顺序执行(很像before块)。与before块的一个核心区别是,您获得了对该变量的显式引用,而不需要回退到示例变量。与
let
块一样,如果多个let!
块被定义为相同的名称,则最近的块将在执行中使用。核心区别在于,如果这样使用,let!
块将被执行多次,而let
块将只执行最后一次。在(:each)块之前
before(:each)
是块之前的默认值,因此可以引用为before {}
,而不是每次都指定完整的before(:each) {}
。我个人倾向于在一些核心情况下使用
before
块,我将在以下情况下使用before块:before { get :index }
),尽管在很多情况下可以使用subject
,但如果不需要引用,有时会感觉更明确。如果您发现自己在为规范编写大型
before
块,请检查工厂,确保完全理解traits及其灵活性。在(:所有)块之前
它们只执行一次,在当前上下文(及其子)的规范之前。如果编写正确,它们可以发挥很大的优势,因为在某些情况下,这可以减少执行和工作量。
一个例子(几乎不会影响执行时间)是模拟测试的ENV变量,您应该只需要做一次。
kwvwclae2#
几乎总是,我更喜欢
let
.你链接的帖子指出let
也更快.然而,有时,当许多命令必须执行时,我可以使用before(:each)
,因为当涉及许多命令时,它的语法更清晰.在您的示例中,我肯定更喜欢使用
let
而不是before(:each)
,一般来说,当只完成一些变量初始化时,我倾向于使用let
。w9apscun3#
还有一个很大的区别没有提到,用
let
定义的变量只有在你第一次调用它的时候才会示例化,所以before(:each)
块会示例化所有变量,而let
让你定义一些变量,你可以在多个测试中使用,它不会自动示例化它们。如果你希望所有的数据都被预先加载,你的测试可能会反过来咬你自己。在某些情况下,你甚至可能想定义一些let
变量,然后使用before(:each)
块调用每个let
示例,只是为了确保数据在开始时可用。tkclm6bt4#
看起来你正在使用Machinist。注意,你可能会看到let的make!inside(非bang版本)在全局fixture事务之外发生一些问题(如果你也在使用事务fixture的话),从而破坏了其他测试的数据。