我正在使用rspec-rails 3.0.0运行Rails 4应用程序并且应该匹配2.5.0,并且我有一个具有一些条件验证的事件模型,如下所示:
class Event < ActiveRecord::Base
validates :name, :location, :time, :city, :zipcode, :user, :state, presence: true
validates :post_text, presence: true, if: :happened?
validates :pre_text, presence: true, unless: :happened?
belongs_to :community
belongs_to :user
belongs_to :state
def happened?
(self.time < Time.now) ? true : false
end
end
我的event_spec.rb看起来像是:
require 'spec_helper'
describe Event do
before { @event = FactoryGirl.build(:future_event) }
subject { @event }
it { should validate_presence_of(:time) }
it { should validate_presence_of(:name) }
it { should validate_presence_of(:location) }
it { should validate_presence_of(:user) }
it { should validate_presence_of(:city) }
it { should validate_presence_of(:state) }
it { should validate_presence_of(:zipcode) }
it { should belong_to(:state) }
it { should belong_to(:user) }
it 'has pre_text if future event' do
expect(FactoryGirl.create(:future_event)).to be_valid
end
it 'has post_text if past event' do
expect(FactoryGirl.create(:past_event)).to be_valid
end
end
但是当我运行测试时,我的it { should validate_presence_of(:time) }
块失败了,因为它继续运行剩余的验证并在条件验证上抛出异常,因为self.time是nil。我通过检查time.present实现了一个hacky修复程序?在发生了什么?方法。但是,任何人都可以帮助我理解测试需要存在另一个字段的条件验证的最佳方法是什么?
答案 0 :(得分:4)
这肯定是迟到的,但对于寻求解决方案的其他人来说。我找到了一种有效的方法:
context "if happened" do
before { allow(subject).to receive(:happened?).and_return(true) }
it { is_expected.to validate_presence_of(:time) }
end
我希望这会有所帮助
答案 1 :(得分:2)
只是一个小小的提示:
def happened?
(self.time < Time.now) ? true : false
end
与
相同def happened?
self.time < Time.now
end
答案 2 :(得分:0)
是的,遗憾的是没有其他办法。事实是,在您保存事件记录之前,time
在技术上被允许为零,所以如果你恰好打电话给#happened?在time
设置之前,将引发异常。因此,如果我编写这段代码,我会亲自检查#happened?,因为无论如何都要处理这种情况(无论实际发生的可能性如何)。