【问题标题】:Rspec subject! alters "position" of a before blockRspec主题!改变前块的“位置”
【发布时间】:2015-02-27 08:34:07
【问题描述】:

我刚刚在 Rspec 中发现了一些东西(在必要的头撞墙之后),我希望有人能阐明这一点。我认为这涉及我对 Rspec 的subject! 的误解。

我的理解是subject! 将运行主题块,无论是否使用subject,并且该块将在适当的时间运行。

似乎发生的事情就是这样 - 具有奇怪的副作用,它会导致 inner subject 块在 内部 @987654325 之前运行@块。

即:

  describe 'subject block' do
    before { @var = nil }

    describe 'Test 1: With a bang' do
      subject! { @var = false }
      describe 'inner describe' do
        before { @var = true }
        subject { @var }
        it { is_expected.to be true }
      end
    end

    describe 'Test 2: Without a bang' do
      subject { @var = false }
      describe 'inner describe' do
        before { @var = true }
        subject { @var }
        it { is_expected.to be true }
      end
    end
  end

这个结果指出了问题所在。测试 1,即在外部块中带有 subject! 的测试失败。而使用非爆炸subject 的测试 2 通过。测试 1 失败的原因是内部 before 块,其中放置了 @var = true,没有在内部 subject 之前调用,因此在实际规范之前没有调用。

这对我来说似乎是错误的。我错过了什么吗?

【问题讨论】:

    标签: ruby-on-rails ruby rspec


    【解决方案1】:

    我的理解是subject! 将运行主题块,无论是否使用subject,并且该块将在适当的时间运行。

    “在适当的时候”是相当模糊的,所以这取决于你的意思。 注意the docs 说了什么:

    就像subject 一样,除了block 是由隐式的before 挂钩调用的。

    所以所有the implementation subject! 所做的只是委托给subject,然后定义一个调用主题的before 钩子。

    当您在多个嵌套级别有before 挂钩时,外部上下文before 挂钩在内部挂钩之前运行,正如您所期望的那样。这正是这里发生的事情。

    RSpec 的 DSL 在使用良好时非常有用,但它也可以混淆事情发生的顺序,当顺序很重要时,我认为你最好将它折叠成一个单独的 it 来完成每件事以适当的顺序(或者可能为初始的主要设置步骤保留一个 before 挂钩)。

    【讨论】:

    • 我所说的“适当时间”是指“与subject 相同的时间”。我假设它会以与使用 subject 相同的顺序运行而不会爆炸,但是由于使用隐式 before 块的实现,我想这是不可能的。谢谢。
    • subject 在运行时没有定义的顺序。它只是定义了一个 subject 辅助方法,只要有东西调用它就会执行——无论是您在规范中的显式调用,还是由is_expected(定义为expect(subject))。整点let!subject! 是在示例之前调用生成的辅助方法,以便它们产生的任何副作用对整个示例都有效。不过,我很少使用这些结构。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    相关资源
    最近更新 更多