RSpec 之前在一个助手中

RSpec before in a helper

是否可以这样做?

module MyHelper
  before (:each) do
    allow(Class).to receive(:method).and_return(true)
  end
end

然后在我的测试中我可以做类似的事情:

RSpec.describe 'My cool test' do
  include MyHelper
  it 'Tests a Class Method' do
    expect { Class.method }.to eq true
  end
end

编辑: 这会产生以下错误:

undefined method `before' for MyHelper:Module (NoMethodError)

基本上我有一个案例,其中许多测试做不同的事情,但它们之间的一个通用模型对 after_commit 做出反应,最终总是调用一个与 API 对话的方法。我不想在全球范围内允许 Class 接收 :method,因为有时我需要自己为特殊情况定义它……但我不想重复我的 allow/receive/and_return而是将其包装在一个通用的助手中...

使用名为 shared_context

的功能可以做您想做的事

您可以使用这样的代码创建共享文件

shared_file.rb

shared_context "stubbing :method on Class" do
  before { allow(Class).to receive(:method).and_return(true) }
end

然后您可以将该上下文包含在您需要的块中的文件中,就像这样

your_spec_file.rb

require 'rails_helper'
require 'shared_file'

RSpec.describe 'My cool test' do
  include_context "stubbing :method on Class"
  it 'Tests a Class Method' do
    expect { Class.method }.to eq true
  end
end

RSpec 比 included/extended 模块助手更自然。假设是"RSpec way"。

您可以将该代码分成 shared_context 并将其包含到示例组(不是示例)中,如下所示:

RSpec.describe 'My cool test' do
  shared_context 'class stub' do
    before (:each) do
      allow(Class).to receive(:method).and_return(true)
    end
  end

  describe "here I am using it" do
    include_context 'class stub'

    it 'Tests a Class Method' do
      expect { Class.method }.to eq true
    end
  end

  describe "here I am not" do
    it 'Tests a Class Method' do
      expect { Class.method }.not_to eq true
    end
  end
end

共享上下文可以包含 let、辅助函数和您需要的所有内容(示例除外)。 https://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-context

您可以创建一个 hook that is triggered via metadata,例如 :type => :api:

RSpec.configure do |c|
  c.before(:each, :type => :api) do
    allow(Class).to receive(:method).and_return(true)
  end
end

在您的规范中:

RSpec.describe 'My cool test', :type => :api do
  it 'Tests a Class Method' do
    expect { Class.method }.to eq true
  end
end

您还可以将 :type => :api 传递给单独的 it 个块。