DRY-ify RSpec测试

时间:2012-08-30 10:23:59

标签: ruby-on-rails-3 rspec

我花了大半个晚上在RSpec上阅读各种文章和演练。虽然我已经学到了很多东西,但我仍然有点保持干燥并且仍然有用。 RSpec很有表现力,但它似乎让初学者难以编写简洁的测试。

我可以看到自己做了很多事情的一件事是测试每个边缘情况的两边,以及单个变量的单个或多个有效值。目前,我有以下内容:

context "when physical address line 1 is too short" do
  before { @contact.physical_addr_line_1 = "1" }

  it { should_not be_valid }
  specify { @contact.save.should_not be_true }
end

context "when physical address line 1 is too long" do
  before { @contact.physical_addr_line_1 = "1"*111 }

  it { should_not be_valid }
  specify { @contact.save.should_not be_true }
end

context "when physical address line 1 is valid length" do
  before { @contact.physical_addr_line_1 = "11111" }

  it { should be_valid }
  specify { @contact.save.should be_true }
end

有没有一种重构方法来清理它?我想在那里添加多个有效值(目前只根据该长度进行检查),并对多个其他地址行变量执行相同的测试集。效率,可读性和可维护性对我来说都很重要,因此任何有关如何更好地接受此类测试或任何推荐阅读的建议都将受到赞赏。

1 个答案:

答案 0 :(得分:0)

你可以把它干这么干。我认为也让它更具可读性。

在前一个块中定义一次有效属性:

before(:each) do
  @attr = #attributes hash
end

context "validations" do

  it "should not accept attribute that is too long" do
     long_string = "a" * unacceptable number
     Model.new(@attr.merge(attribute: long_string)).should_not be_valid
  end

  it "should not accept attribute that is too short" do
     short_string = "a" * unacceptable number
     Model.new(@attr.merge(attribute: short_string)).should_not be_valid
  end
end

此外,theaa宝石非常棒。 https://github.com/thoughtbot/shoulda

它允许编写如下测试:

it {should ensure_length_of(:attribute).is_at_least(n).is_at_most(n)}