3

我正在为自己制作一个小应用程序,按照 Michael Hartl 的 Rails 教程来提高我的技能。

嗯,对我来说最大的困难是 TDD ......我开始有点习惯了,但在这一点上我面临一个小问题:我有很多重复测试,因为我的一个模型有很多属性是百分比.

我在模型规范文件中重构了这些属性的测试:

describe Measure do

  let(:user) { FactoryGirl.create(:user) }
  before do
    @measure = user.measures.build(
                fat: 35.0,
                water: 48.0,
                muscle: 25.5,
                bmi: 33.0
              )
  end

  subject { @measure }

  describe 'validations' do

    describe 'percentage attributes validations' do

      percentages = %w[bmi fat muscle water]

      percentages.each do |percentage|

        describe "#{percentage} should be a number" do
          before { @measure.send("#{percentage}=".to_sym, 'value') }  
          it { should_not be_valid }
        end
      end

      percentages.each do |percentage|
        describe "#{percentage} should be positive" do
          before { @measure.send("#{percentage}=".to_sym, -1) }
          it { should_not be_valid }
        end
      end

      percentages.each do |percentage|
        describe "#{percentage} should be less or equal to 100" do
          before { @measure.send("#{percentage}=".to_sym, 100.01) }
          it { should_not be_valid }
        end
      end
    end
  end
end

但这又很长,我认为制作 Rails 教程第 8 章中介绍的 RSspec 自定义匹配器可能是一个好主意。

所以我觉得测试可以这样写

describe 'percentage attributes validations' do
  its(:bmi) { should be_a_percentage }
end

使用be_a_percentage自定义匹配器。但我被困住了,因为我不知道如何实现它......到目前为止我有:

RSpec::Matchers.define :be_a_percentage |percentage| do
  match |measure| do
    # What should I do ?
    # percentage is nil and number is the attribute value
    # I can't call be_valid on the Measure object
  end
end

我尝试了不同的电话

describe 'percentage attributes validations' do

  specify { @measure.bmi.should be_a_percentage }

end

我阅读了有关自定义匹配器链接的内容,但我不明白。

这是我的第一篇文章,它很长,所以我提前感谢你的帮助......

4

1 回答 1

1

这并没有真正回答您的直接问题,但是随着代码库大小的增加,您可能希望保持原样,而不是将测试隐藏在be_a_percentage自定义和隐藏的方法中。将其保留在那里,尽管有点冗长,但可以确保您知道要测试的内容,而不必考虑be_a_percentage实际含义。毕竟,减少的百分比是负的。我的2美分..

无论如何,我们可以继续干燥您的代码:

shared_examples_for 'percentage' do |percentage|
  describe "#{percentage} should be a number" do
    before { @measure.send("#{percentage}=".to_sym, 'value') }  
    it { should_not be_valid }
  end

  describe "#{percentage} should be positive" do
    before { @measure.send("#{percentage}=".to_sym, -1) }
    it { should_not be_valid }
  end

  describe "#{percentage} should be less or equal to 100" do
    before { @measure.send("#{percentage}=".to_sym, 100.01) }
    it { should_not be_valid }
  end
end

describe 'validations' do
  describe 'percentage attributes validations' do

    percentages = %w[bmi fat muscle water]

    percentages.each do |percentage|
      it_should_behave_like 'percentage'
    end
  end
end

参考:RSpec 共享示例

于 2013-01-08T02:43:35.833 回答