Rspec主题!改变"位置"之前的块

时间:2015-02-26 22:24:36

标签: ruby-on-rails ruby rspec

我刚刚在Rspec发现了一些东西(在必要的撞击墙头之后),我希望有人可以照亮它。我认为这涉及到我对Rspec' subject!的误解。

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

似乎发生的事情就是这样 - 由于奇怪的副作用,它会导致内部 subject块在内部之前运行 before阻止。

即便:

  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!的测试失败。而测试2,使用非爆炸subject,通过。测试1失败的原因是放置before的内部@var = true块未在内部subject之前调用,因此在实际规范之前未调用。

这对我来说似乎不对。我错过了什么吗?

1 个答案:

答案 0 :(得分:3)

  

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

"在适当的时间"是非常模糊的,所以这取决于你的意思。 请注意the docs说的是什么:

  

就像subject一样,除了隐含的前挂钩调用block之外。

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

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

RSpec的DSL在使用得很好时非常有用,但它也可以模糊处理事件的顺序,当排序很重要时,我认为你最好将它折叠成一个{ {1}}以适当的顺序执行每个操作(或者可能为初始的主设置步骤保留一个it挂钩)。