gpt4 book ai didi

ruby-on-rails - RSpec:let 和 before block 有什么区别?

转载 作者:行者123 更新时间:2023-12-02 07:43:45 25 4
gpt4 key购买 nike

let 和有什么区别和 before在 RSpec 中阻塞?

以及何时使用每个?

在下面的示例中,什么是好的方法(让或之前)?

let(:user) { User.make !}
let(:account) {user.account.make!}

before(:each) do
@user = User.make!
@account = @user.account.make!
end

我研究了这个 stackoverflow post

但是为上面的关联内容定义 let 是否很好?

最佳答案

人们似乎已经解释了他们不同的一些基本方式,但忽略了before(:all)并且不要确切解释为什么应该使用它们。

我相信实例变量在绝大多数规范中都没有使用,部分原因是 this answer 中提到的原因。 ,所以我不会在这里提到它们作为一个选项。

让 block
let 中的代码块仅在引用时执行,延迟加载这意味着这些 block 的顺序无关紧要。这为您提供了大量功能,可以通过您的规范减少重复设置。

一个(非常小且做作的)示例是:

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

你可以看到 has_moustache在每种情况下定义不同,但无需重复 subject定义。需要注意的重要一点是最后一个 let将使用当前上下文中定义的 block 。这对于设置用于大多数规范的默认值很有用,如果需要,可以将其覆盖。

例如,检查 calculate_awesome 的返回值如果通过 person型号为 top_hat设置为 true,但没有 mustache 将是:
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

关于 let block 需要注意的另一件事,如果您正在搜索已保存到数据库中的内容(即 Library.find_awesome_people(search_criteria) ),则不应使用它们,因为除非它们已经被引用,否则它们不会被保存到数据库中。 let!before block 是应该在这里使用的。

另外,永远不要 曾经使用 before触发 let 的执行 block ,这就是 let!是为!

让! block
let! block 按照它们定义的顺序执行(很像之前的 block )。与 before block 的一个核心区别是您获得了对该变量的显式引用,而不是需要回退到实例变量。

let 一样 block ,如果有多个 let! block 以相同的名称定义,最新的是将在执行中使用的。核心区别在于 let!如果像这样使用, block 将被执行多次,而 let block 只会执行最后一次。

before(:each) block
before(:each)是默认的 before block ,因此可以引用为 before {}而不是指定完整的 before(:each) {}每一次。

我个人偏好使用 before在一些核心情况下阻塞。如果出现以下情况,我将使用 before block :
  • 我正在使用模拟、 stub 或 double
  • 有任何合理大小的设置(通常这表明您的工厂特性设置不正确)
  • 有许多变量我不需要直接引用,但设置需要
  • 我在 Rails 中编写功能 Controller 测试,我想执行一个特定的测试请求(即 before { get :index } )。即使您可以使用 subject在很多情况下,如果您不需要引用,有时会感觉更明确。

  • 如果你发现自己写得很大 before为您的规范设置 block ,检查您的工厂并确保您完全了解特征及其灵 active 。

    before(:all) block

    这些只会在当前上下文(及其子项)中的规范之前执行一次。如果编写正确,这些可以发挥很大的优势,因为在某些情况下,这可以减少执行和工作量。

    一个例子(几乎不会影响执行时间)是模拟一个 ENV 变量进行测试,你应该只需要做一次。

    希望有帮助:)

    关于ruby-on-rails - RSpec:let 和 before block 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5974360/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com