【问题标题】:RSpec around() block behaves different from a before() + after()RSpec around() 块的行为与 before() + after() 不同
【发布时间】:2016-01-27 20:05:18
【问题描述】:

我正在使用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() 块不同?

【问题讨论】:

  • 基于docsaround 实现了与beforeafter 类似的目标。但是“around 钩子不会像 beforeafter 钩子那样与示例共享状态。”查看文档;里面也有很多例子。
  • 我认为这回答了它,我在阅读文档时错过了它。谢谢!如果您想将评论移至某个答案,我很乐意将其标记为已回答。
  • 另请注意,您的#some global before() setup 块实际上会在 around 块内运行——这很可能是这里的原因,因为我假设 global setup 块会重置租户

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


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 2021-08-21
    • 2014-07-18
    相关资源
    最近更新 更多