Rspec:运行 除非列入白名单,否则对每个模型进行特定单元测试

Rspec: Run specific unit test on every model unless whitelisted

我有一个多租户 SaaS 应用程序。我 运行 对每个租户模型进行了租户安全测试。

describe 'tenant security' do
  it "has only the current company's data" do
    set_tenant_company
    other_companys_data = create :model

    set_tenant_company
    this_companys_data = create :model

    expect(Model.all).to include this_companys_data
    expect(Model.all).not_to include other_companys_data
  end
end

有没有办法在每个模型上使用元编程运行? [没有明确地将任何代码写入单元测试]如果是这样,是否有办法将非租户模型列入白名单?

租户安全至关重要,我不希望它被无意中忽视。

根据 Pedro 的评论,以及他向 RSpec 核心团队提出的问题:

创建一个共享示例,其中包含要隐式包含在每个模型中的测试。 :unless 条件适用于不应包含此测试的白名单模型。

RSpec.shared_examples 'a tenant model' do
  it "has only the current company's data",unless: metadata[:not_a_tenant_model] == true do
    set_tenant_company
    other_companys_data = create subject.class.name.underscore.to_sym

    set_tenant_company
    this_companys_data = create subject.class.name.underscore.to_sym

    expect(subject.class.all).to include this_companys_data
    expect(subject.class.all).not_to include other_companys_data
  end
end

将以下行放入 RSpec.configuration

RSpec.configure do |config|
  config.include_context 'a tenant model', type: :model
end

这具有在每个模型中放置以下内容的效果。

Rspec.describe TenantModel do
  it_behaves_like 'a tenant model'
end

要将非租户模型列入白名单,只需添加适当的标签:

RSpec.decribe NonTenantModel, :not_a_tenant_model do
  # shared example will not be included
end

非常感谢!佩德罗和 RSpec 核心团队。

目前接受的解决方案需要具体标记每个非租户模型。使用此解决方案,您可以在配置中执行此操作。

好吧,感谢打开这个问题:https://github.com/rspec/rspec-core/issues/2480,这似乎是最适合你的情况的解决方案:

non_tenant_models = %w(NonTenantModelOne NonTenantModelTwo).map(&:constantize)

RSpec.configure do |c|
  c.define_derived_metadata(type: :model) do |meta|
    meta[:tenant_model] = true unless meta[:described_class].presence_in non_tenant_models
  end

  c.include_context "shared", tenant_model: true
end

这为您提供明确的元数据,说明模型是否为租户,并将 运行 共享示例指定的每个非租户模型列入白名单,无需在模型中编写任何代码。