通过RSpec测试套件对ActiveRecord进行验证验证

时间:2016-02-09 04:35:12

标签: ruby-on-rails ruby unit-testing rspec tdd

我有一个ActiveRecord对象,可以在我的RSpec套件的大约50%中创建/保存。 我想在整个套件中对它进行验证,除了我明确测试验证行为的上下文。

为实现这一目标,我使用config

对其进行全局存取
config.before(:each) do
  allow_any_instance_of(Activerecord::Abc).to receive(:abc_validate).and_return(true)
end

然后在特定上下文中覆盖存根

context "Validations" do
  context "abc_validate" do
    before :each do
      allow_any_instance_of(Activerecord::Abc).to receive(:abc_validate).and_call_original
    end

    it "should ..... " do
      ........
    end
  end
end

这符合我的要求。但是,它效率不高,因为虽然我只需要大约50%的RSpec测试套件存根,但我实际上是为每个单元测试存根。即使是不需要存根的单元测试也会有一个存根功能。

有更好的方法吗?

我想到了另一种方法:我可以在RSpec中重新打开该类,并覆盖自定义验证函数本身,而不是对方法进行存根。

Activerecord::Abc.class_eval do
  def abc_validate(testing_self = false)
    testing_self ? super : true
  end
end

然而,这种方法感觉太黑了。

版本详情 -

  1. Rails 4.2.4
  2. Rspec 3.3.0

1 个答案:

答案 0 :(得分:0)

就我个人而言,我不喜欢在整个套件中使用无效模拟对象的想法。我认为它容易出现错误,因为测试会将对象视为有效对象,并且可能会使用对象的功能,从而导致其无效,从而导致错误否定。

因此,我建议您在整个测试过程中使用有效对象来解决问题,并考虑您正在测试其创建和验证的特定上下文。

如果创建有效对象需要进行大量设置,则可以使用fixturesFactoryGirl gem将此逻辑集中在一个位置。创建有效对象将是调用FactoryGirl.create(:abc)的简单问题。