Rails 3 user check and shoulda

These days takes place between Shoulda and Rspec. I read and played around honest with RSpec, but not so much with Shoulda. I find that a single line statement is easier to read and the test looks cleaner. But when I cannot figure out how to write a specific statement in Shoulda, I will switch to RSpec. However, this is not very pleasing.

So here is what I did today. I wrote some custom checks for my Course model. The course has start_date and end_date. . It has a few rules.

  • start_date and end_date are required
  • start_date cannot be later than today
  • end_date cannot be before start_date

I know that there are several stones that could do this for me. But since I'm new, I thought it might be a good idea to do it myself and learn when I go.

So my model looks like

 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, :presence => true, :course_end_date=>true end 

My user checks look like this

 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, attribute, value) if object.errors[attribute].blank? if value < DateTime.now.to_date object.errors[attribute] << "cannot be later than today" end end end end 

And my next course_special

 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 

Now, before I wrote the last "it" block using Rspec, I had something similar in the context of my validation.

 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 

And I got the next crash

 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)"] 

Not sure what I'm doing wrong here. Is my custom validation code incorrect or do I need to configure something before I run the last statement so that start_date is not null when testing end_date?

Checks work great in a view. I mean, I get the correct validation errors depending on the type of data that I entered. But the test fails. I looked at this for a while, but I can’t understand what exactly I am doing wrong.

+4
source share
2 answers

I think you could solve this in one of two ways:

Or you need to put you date = DateTime.now.to_date in the before(:each) block.

 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 

Or you can use date rail helpers.

 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 
+3
source

@nickgrim already answered the question, but I want to add a comment. The point of describe and it is to encourage sentences starting with the words "describe" and "this." In your example, you have the following:

 it " end date should not be before course start date" do # ... 

"end date ..." is not an offer. Please write something like:

 it "validates that end date should be >= start date" do 
0
source

Source: https://habr.com/ru/post/1386999/


All Articles