重用RSpec行为验证

kol*_*rie 5 code-reuse rspec ruby-on-rails

在我的Rails 3应用程序,我有一个RSpec的规范,检查某一领域(的行为角色用户模型),以保证该值有效值的列表中.

现在,我将为另一个字段提供完全相同的规范,在另一个具有另一组有效值的模型中.我想提取公共代码,而不是仅仅复制和粘贴它,更改变量.

我想知道是否会使用共享示例或其他RSpec重用技术.

这是相关的RSpec代码:

describe "validation" do  
  describe "#role" do
    context "with a valid role value" do
      it "is valid" do
        User::ROLES.each do |role|
          build(:user, :role => role).should be_valid
        end
      end
    end

    context "with an empty role" do
      subject { build(:user, :role => nil) }

      it "is invalid" do
        subject.should_not be_valid
      end

      it "adds an error message for the role" do
        subject.save.should be_false
        subject.errors.messages[:role].first.should == "can't be blank"
      end
    end

    context "with an invalid role value" do
      subject { build(:user, :role => 'unknown') }

      it "is invalid" do
        subject.should_not be_valid
      end

      it "adds an error message for the role" do
        subject.save.should be_false
        subject.errors.messages[:role].first.should =~ /unknown isn't a valid role/
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

重用此代码的最佳情况是什么,但是将角色(正在验证的字段)和User :: ROLES(有效值的集合)提取到传递给此代码的参数中?

Chr*_*erg 2

我认为这是共享示例的一个完全合理的用例。例如这样的东西:

shared_examples_for "attribute in collection" do |attr_name, valid_values|

  context "with a valid role value" do
    it "is valid" do
      valid_values.each do |role|
        build(:user, attr_name => role).should be_valid
      end
    end
  end

  context "with an empty #{attr_name}" do
    subject { build(:user, attr_name => nil) }

    it "is invalid" do
      subject.should_not be_valid
    end

    it "adds an error message for the #{attr_name}" do
      subject.save.should be_false
      subject.errors.messages[attr_name].first.should == "can't be blank"
    end
  end

  context "with an invalid #{attr_name} value" do
    subject { build(:user, attr_name => 'unknown') }

    it "is invalid" do
      subject.should_not be_valid
    end

    it "adds an error message for the #{attr_name}" do
      subject.save.should be_false
      subject.errors.messages[attr_name].first.should =~ /unknown isn't a valid #{attr_name}/
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

然后你可以在你的规范中这样称呼它:

describe "validation" do  
  describe "#role" do
    behaves_like "attribute in collection", :role, User::ROLES
  end
end
Run Code Online (Sandbox Code Playgroud)

还没有测试过这个,但我认为它应该有效。