【问题标题】:Change the order of before hooks in rspec在 rspec 中更改前钩子的顺序
【发布时间】:2013-07-22 00:28:34
【问题描述】:

我有一个这样的控制器规格:

describe "#create" do
  before { post 'create', params }
  context "when the artist is valid" do
    before { allow(artist).to receive(:save).and_return(true) }
    it { expect(page).to redirect_to(root_path) }
    it { expect(notifier).to have_received(:notify) }
  end
end

这是一个简单的规范,但它不起作用,因为 describe 的 before 块在 context 的 before 块之前执行。因此,artist.save 的结果在调用 create 操作时不会被存根。

它试图这样做:

describe "first describe" do
  before { puts 2 }
  describe "second describe" do
    before { puts 1 }
    it "simple spec" do
      expect(1).to eq 1
    end
  end
end

我在“1”之前看到“2”。我不确定,但我认为它适用于以前的版本。

我知道,我可以做到:

describe "#create" do
  context "when the artist is valid" do
    before { allow(artist).to receive(:save).and_return(true) }
    it "redirect to the root path" do
      post 'create', params
      expect(page).to redirect_to(root_path)
    end

    it "do notifications" do
      post :create, params
      expect(notifier).to have_received(:notify)
    end
  end
end

但我认为它不太干净。

我发现,在这个页面上,http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/Hooks#before-instance_method 的顺序应该是这样的:

before(:suite) # declared in RSpec.configure
before(:all)   # declared in RSpec.configure
before(:all)   # declared in a parent group
before(:all)   # declared in the current group
before(:each)  # declared in RSpec.configure
before(:each)  # declared in a parent group
before(:each)  # declared in the current group

这个例子不是这样的。

我不确定,但我认为它适用于旧版本的 rspec。

有解决办法吗?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 rspec


    【解决方案1】:

    我强烈建议您不要更改 rspec 中的钩子顺序。这将使您的应用程序非标准,而 Rails 是基于标准构建的,并且可以按预期工作。

    您所描述的一切都“按设计”。外部前块总是在内部块之前调用。

    您认为“不太干净”的示例是进行控制器规格的标准方法。我实际上鼓励您这样做,以便它更易于维护/可读。在我看来,它一点也不脏。

    也就是说,有一些选择:

    1. 您可以使用一种方法。我不止一次拥有do_post 或类似的方法
    2. 您可以使用延迟初始化的let 块。如果它依赖于其他先运行的块,我会发现它是 unlcean,但它是一个选项。
    3. 您可以定义subjecthttps://www.relishapp.com/rspec/rspec-core/v/2-6/docs/subject/explicit-subject

    【讨论】:

    • 我同意。我已经尝试过其中一些解决方案,但我没有尝试将 post 调用放在 before 块中。我将创建一个类似 subject(:do_post) { post 'create', args } 的主题,并在上​​下文的 before 块中调用 do_post 函数。
    • 我建议使用let,而不是subject。然后叫它:post_response。所以:let(:post_response) { post 'create', args }
    猜你喜欢
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多