Rspec:除非列入白名单,否则在每个型号上运行特定的单元测试

时间:2017-11-16 04:54:26

标签: ruby-on-rails unit-testing rspec multi-tenant

我有一个多租户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

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

租户安全至关重要,我不想忽视它。

2 个答案:

答案 0 :(得分:0)

根据Pedro的评论,他的问题发布在RSpec核心团队:

使用您希望隐式包含在每个模型中的测试创建一个共享示例。 :除非条件适用于不应包含此测试的白名单模型。

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核心团队。

答案 1 :(得分:0)

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

好吧,感谢您打开这个问题: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

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