Rspec 组合多个let语句

Rspec 组合多个let语句,rspec,Rspec,如何定义一个方法create\u all,使我能够代替编写 describe "some spec" do let(:a) { create :a } let(:b) { create :b, :a => a } ... 写 describe "some spec" do create_all ... 更具体地说:我必须在哪里定义它才能在描述上下文中使用它 它应该可以跨不同的规范文件工作。我认为您可以将方法定义放置在此文件中的任何位置(甚至在其他文件夹中-例如spe

如何定义一个方法
create\u all
,使我能够代替编写

describe "some spec" do
  let(:a) { create :a }
  let(:b) { create :b, :a => a }
  ...

describe "some spec" do
  create_all
  ...
更具体地说:我必须在哪里定义它才能在
描述
上下文中使用它


它应该可以跨不同的规范文件工作。

我认为您可以将方法定义放置在此文件中的任何位置(甚至在其他文件夹中-例如
spec/support
),但不在
It
块中。您需要在测试中触发它(例如在
之前的
块中)

PS您提到您想在
描述
上下文中使用
创建所有
。我认为这是不可能的,因为(我相信)RSpec解析spec文件并只运行必要的代码:所有
块之前,所有
等。RSpec不执行其他操作

PPS 据我所知,您希望使用延迟加载。这只是一个可能对你有帮助的想法。你可以

  • 使用创建数据的方法在
    spec/support
    中创建模块

  • 在测试文件中包括您的模块(例如
    user_spec.rb
    )-定义的方法现在应该在此文件中可用

  • 在测试中使用这些方法


  • 我认为这种行为应该类似于延迟加载。您可以在不同规范中使用方法(仅包括模块)

    spec/support
    目录下创建模块

    module ApplicationMacros
      def create_all
        a = create(:a)
        b = create(:b, a: a)
      end
    end
    
    将其放入
    spec/spec\u helper.rb

    Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
    
    最后从您的
    description
    块调用
    create\u all

    describe "some spec" do
      before :all do      
       create_all
      end
      .........
    end
    

    关键是使用而不是
    config。在
    spec/spec\u helper.rb
    中包含
    。
    因此,首先我们创建一个模块
    descripebhelper

    module DescribeHelper
      def create_all
        let(:a) { create :a }
        let(:b) { create :b, :a => a }
      end
    end
    
    spec/support/description_helper.rb的内部

    然后,在
    spec/spec\u helper.rb中,我们必须执行以下操作

    ...
    
    RSpec.configure do |config|
      ...
      config.extend  DescribeHelper
      ...
    end
    
    ...
    

    这将导致
    create\u all
    description
    块中可用。

    RSpec中有一种机制来实现这一点,它是
    共享的\u上下文。它简单、优雅,不需要像其他一些选项那样跳圈

    因此,在您的示例中,您设置了一个共享上下文:

    # spec/support/create_all.rb
    
    shared_context "create all" do
      let(:a) { create :a }
      let(:b) { create :b, :a => a }
      ...
    end
    
    那么在你的规格里呢

    # some_spec.rb
    
    describe "some spec" do
      include_context "create all"
    
      it "tests something" do
        ...
      end
    end
    
    进一步阅读:


    虽然这会起作用,但我正在寻找一种可以跨不同规格使用的解决方案。因此,请使用其他回答中所述的支持文件夹和模块谢谢!包括它将不起作用,扩展将。但正如你在我的回答中所看到的,我找到了一种更好的方法来定义所有规格的产品,但这不起作用。spec_helper中包含的模块方法仅在“it”上下文中可见,而在“descripe”上下文中不可见。试一试(我试过了)。你编辑过的答案可以用,但却忽略了“让”的优点。()我确实特别想使用let,而不是before块。这就是共享上下文的目的-请参见下面的我的答案如果这个答案不在这里,我会添加它。是的,让我惊讶的是它没有。这是共享上下文背后的目的,并避免了其他一些更复杂的路由到同一端。@ RichardJordan,你认为你的答案比我发现的方式更能达到预期效果吗?我认为这是解决这类问题的“正确”(在编程中从来不是一个理想的词)方法。意见可能不同,但这是我所用的,也是我教给别人的。@RichardJordan我明白了。不过,我在回答中这样做的方式有一个优点:它允许我扩展所有规范(或所有特定类型)的上下文,而不必在每个规范中显式地进行扩展。就像普通的规范助手一样。
    # some_spec.rb
    
    describe "some spec" do
      include_context "create all"
    
      it "tests something" do
        ...
      end
    end