RSpec around()块的行为与before()+ after()不同

时间:2016-01-27 20:05:19

标签: ruby-on-rails rspec apartment-gem

我使用apartment gem管理多租户Rails应用。

旁注:如果您不熟悉gem,切换公寓只需切换Postgres DB后端使用的架构。您使用Apartment::Tenant.switch!(apartment)

更改了公寓租户

我有几个测试在某个公寓租户的背景下测试行为。为此,我使用以下设置(显示控制器规格的示例)

RSpec.describe MyController, type: :controller do
  before(:each) do
    # Some global before() setup
  end

  context "foo apartment" do

    ### Option 1 - Using the around() hook
    around(:each) do |example|
      begin
        Apartment::Tenant.switch!("foo")
        example.run
      ensure
        Apartment::Tenant.switch!("public")
      end
    end

    ### Option 2 - Independent before() + after() hooks
    before(:each) { Apartment::Tenant.switch!("foo") }
    after(:each) { Apartment::Tenant.switch!("public") }


    it "tests that the foo apartment is being used" do
      expect(Apartment::Tenant.current).to eq("foo")
    end
  end
end

如您所见,设置测试有两种方法。一个使用around()钩子,另一个使用相同的东西,但独立使用before()after()钩子。

我想象这两种方法都是等价且可互换的。但令人惊讶的是,只有选项2才有效。

这种行为有原因吗? around()块的运行顺序是否与before()块的顺序不同?

1 个答案:

答案 0 :(得分:2)

around(:each)块将包装所有before(:each)块(甚至是在外部作用域级别定义的块)。因此,如果您选择1围绕阻止,您将获得以下行为

around_before
  global before() setup block
  example runs
around_after

如果您的全局设置功能块设置了默认租户或其他任何内容,则会覆盖您在周围区域中执行的操作

选项2,你得到

global before() setup block
before block
example runs
after block