ruby-on-rails – Rails 3自定义验证和shoulda
这些天我在Shoulda和Rspec之间摇摆不定.我已经阅读并在RSpec上玩了很多,但与Shoulda没那么多.我发现Shoulda的一行断言更容易阅读,测试看起来更清晰.但是,当我无法弄清楚如何在Shoulda中编写特定的断言时,我会切换到RSpec.虽然不是很开心.
所以这就是我今天所做的.我为我的模型课程写了一些自定义验证.课程有一个start_date和一个end_date.围绕它有一些规则. > start_date和end_date都是必需的 我知道那里有一些安静的东西可以为我做的.但是因为我是新人,我认为自己做这件事可能是个好主意,并在我去的时候学习. 所以这就是我的模型 class Course < ActiveRecord::Base belongs_to :category has_many :batches,:dependent => :destroy accepts_nested_attributes_for :batches,:reject_if => lambda {|a| a[:code].blank?},:allow_destroy => true has_and_belongs_to_many :students,:uniq => true validates_presence_of :name,:course_code,:total_seats validates_uniqueness_of :category_id,:scope => [:name,:course_code] validates :start_date,:presence => true,:course_start_date=>true validates :end_date,:course_end_date=>true end 我的自定义验证如下 class CourseEndDateValidator < ActiveModel::EachValidator def validate_each(object,attribute,value) if object.errors[attribute].blank? && object.errors[:start_date].blank? if value < object.start_date object.errors[attribute] << "cannot be later than start date" end end end end class CourseStartDateValidator < ActiveModel::EachValidator def validate_each(object,value) if object.errors[attribute].blank? if value < DateTime.now.to_date object.errors[attribute] << "cannot be later than today" end end end end 以下是我的course_spec require 'spec_helper'require 'date' describe Course do context 'validations' do it { should validate_presence_of(:name)} it { should validate_presence_of(:course_code)} it { should validate_presence_of(:start_date)} it { should validate_presence_of(:end_date)} it { should validate_presence_of(:total_seats)} date = DateTime.now.to_date it { should allow_value(date).for(:start_date) } it { should_not allow_value(date - 10 ).for(:start_date) } it {should allow_value(date + 10).for(:end_date)} end context 'associations' do it { should belong_to(:category)} it { should have_many(:batches).dependent(:destroy)} it { should have_and_belong_to_many(:students) } end it " end date should not be before course start date" do course = FactoryGirl.build(:course,:end_date=>'2011-12-10') course.should be_invalid end end 在我使用Rspec编写最后一个“it”块之前,我在验证上下文中有类似的内容 context 'validations' do it { should validate_presence_of(:name)} it { should validate_presence_of(:course_code)} it { should validate_presence_of(:start_date)} it { should validate_presence_of(:end_date)} it { should validate_presence_of(:total_seats)} date = DateTime.now.to_date it { should allow_value(date).for(:start_date) } it { should_not allow_value(date - 10 ).for(:start_date) } it { should allow_value(date + 10).for(:end_date)} it { should_not allow_value(date - 10).for(:end_date)} # <------------------- end 我得到了以下失败 Failures: 1) Course validations Failure/Error: it { should_not allow_value(date - 10).for(:end_date)} Expected errors when end_date is set to Fri,9 Dec 2011,got errors: ["name can't be blank (nil)","course_code can't be blank (nil)","total_seats can't be blank (nil)","start_date can't be blank (nil)"] 我不确定我在这里做错了什么.这是我的自定义验证代码不正确还是我需要在运行最后一个断言之前设置一些东西,以便在测试end_date时start_date不是nil? 验证在视图中正常工作.我的意思是我得到了正确的验证错误,具体取决于我输入的数据类型.但我的测试失败了.我现在已经看了一段时间,但无法弄清楚我到底做错了什么. 解决方法
我想你可以用两种方式解决这个问题:
您需要将date = DateTime.now.to_date放入before(:each)块之前. context 'validations' do before(:each) { date = DateTime.now.to_date } it { should allow_value(date).for(:start_date) } it { should_not allow_value(date - 10 ).for(:start_date) } it { should allow_value(date + 10).for(:end_date)} it { should_not allow_value(date - 10).for(:end_date)} end 或者您可以使用rails日期助手. context 'validations' do it { should allow_value(Date.today).for(:start_date) } it { should_not allow_value(10.days.ago).for(:start_date) } it { should allow_value(10.days.from_now).for(:end_date)} it { should_not allow_value(10.days.ago).for(:end_date)} end (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |