ruby-on-rails - 保持干燥,但由于不同原因想要重复

标签 ruby-on-rails ruby rspec dry

所以在我为我的 RoR 模型不断发展的 rspecs 中,我最终得到了两个完全相同的测试:

it 'is valid when x is zero' do
    foo = build(:foo, x: 0, y: 10)
    expect(foo.valid?).to be_truthy
end
it 'is valid when y is ten' do
    foo = build(:foo, x: 0, y: 10)
    expect(foo.valid?).to be_truthy
end

这是因为我首先编写了验证 x 的规范,然后添加了 y 的规范。

显然,是时候重构了。我可以删除其中一个规范,因为它们是重复的:保持干燥。

现在,每个规范的内部结构可能完全相同,但it 描述不同。我不想丢失其中包含的信息。

我的问题是 - 在这种情况下,保持重复的规范完整是否可以接受,或者我应该“合并”它们并改写 it 描述?也许:

it 'is valid when x is zero and y is ten' do
    foo = build(:foo, x: 0, y: 10)
    expect(foo.valid?).to be_truthy
end

但在我看来,我现在有一个规范正在测试两件事(Foo 模型中的两个验证子句)。那也不好。有一股气味潜伏。

还有我错过的另一种方法吗?

最佳答案

我不太担心 DRY,而更担心编写实际涵盖您想要的行为的规范。

it 'is valid when x is zero' do
  foo = build(:foo, x: 0)
  expect(foo.valid?).to be_truthy
end

这个例子实际上根本没有涵盖你的验证!如果您在模型中注释掉验证,它仍然会通过。

测试模型验证时的一些提示:

  • 避免使用工厂。只需使用 .new 和被测属性进行初始化即可。
  • 测试无效和有效输入。
  • 描述验证行为 - 而不是可接受的值。
  • 单独测试每个验证 - 您的集成和功能规范通常会涵盖整个验证。

RSpec.describe Foo do
  describe "validations" do
    describe 'x' do
      it "validates that x is a number between 1 and 10" do
        expect(Foo.new(500).valid?.errors[:x]).to include "must be less than or equal to 10".
        expect(Foo.new(10).valid?.errors).to_not have_key :x
      end
    end

    describe 'y' do
      it "validates that y is a number that is less than 15" do
        expect(Foo.new(500).valid?.errors[:y]).to include "must be less than 15".
        expect(Foo.new(10).valid?.errors).to_not have_key :y
      end
    end
  end
end

关于ruby-on-rails - 保持干燥,但由于不同原因想要重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40047683/

相关文章:

ruby-on-rails - 如何自定义 Capistranos SSH 命令?

ruby-on-rails - Capistrano 杀死 Assets :precompile

ruby - 在 Ruby 脚本中接受命令行参数

ruby - Rspec 限制方法的重用

javascript - 如何在 Capybara 验收测试中 stub JavaScript 延迟?

ruby-on-rails - 如何分析我的 rspec 测试以找到最大的内存消耗?

mysql - Rails JSON API : limit has_many relationship to current_user

ruby-on-rails - 由于 'eventmachine 1.0.3',无法 bundle 安装

ruby-on-rails - "rake test:functionals"是做什么的?

带有 X509 证书的 Ruby SOAP 响应未通过 XML SignatureValue 验证