2013-03-14 66 views
0

我对学校的模式有一个有很多的关联与它的学生以及一对一ASSOCATION与具有用户容量领域的许可证。我想强加验证来限制学生的大小许可证容量的,所以我有以下建立到位:协会大小/限制验证在规范测试失败

class School < ActiveRecord::Base  

    has_one :license 
    has_many :students 

    delegate :user_capacity, :to => :license 

    validate :within_user_capacity  

    def within_user_capacity 
    return if students.blank? 
    errors.add(:students, "too many") if students.size > user_capacity 
    end  

end 

这是我使用来测试这个验证规范, 假定的100用户容量:

it "should fail validation when student size exceeds school's user capacity" do 
    school = FactoryGirl.create(:school_with_license) 
    puts school.user_capacity # => 100 
    puts school.students.size # => 0 
    0...100.times {|i| school.students.build(...)} 
    puts school.students.size # => 100 
    #build the 101st student to trigger user capacity validation 
    school.students.build(...).should_not be_valid 
end 

然而,这总是导致失败 - 我看到消息:

Failure/Error: school.students.build(...).should_not be_valid 
     expected valid? to return false, got true 

编辑

似乎是FactoryGirl一个问题,该规范内卖出期权的语句告诉我,该协会规模正在增加,但该模型作为验证内部进一步调试触发表明,它永远不会增加。即使我明确地将构建的记录保存在spec循环中。

回答

1

看起来您声称上次添加的学生无效(build返回新学生),当您要声明学校无效时。你需要做这样的事情吗?:

school.students.build(...) 
school.should_not be_valid 
+0

善于思考,我想我正在寻找的是一个验证错误作为最后一个学生建立并超出了'user_capacity'尽快触发。这是否意味着我需要将验证移动到学生模型中?它并不完全让学校业务逻辑在学生模型中发生。无论如何,我试图断言学校的有效性而不是你所建议的那样,而且我还没有取得任何成功。 – Noz 2013-03-14 20:44:29

+1

Rails模型的验证通常在调用'valid?'方法(通常作为'save'方法的副作用)而不是属性更改时触发。将验证移动到学生课是没有意义的,因为它关于学校的业务逻辑不是个别学生。我看不出为什么你的测试仍然失败,找出为什么我会尽快在'within_user_capacity'方法中添加'puts'语句来确认它被调用,并且'students.size'是你期望的。 – Steve 2013-03-14 21:00:07

0

尝试做简单的验证,没有委派。

我检查你的方法在我的应用程序,它通常与修复,史蒂夫在他的回答表明(School应该检查的有效性)的作品。

所以我建议以下代码:

class School < ActiveRecord::Base  
    has_many :students 

    validate :within_user_capacity  

    def within_user_capacity 
    errors.add(:students, "too many") if students.size > 1 
    end  
end 

接下来,打开控制台:RAILS_ENV=test rails c

> school = FactoryGirl.create :school 
> school.valid? 
=> true 
> school.students.build 
> school.students.size 
=> 1 
> school.valid? 
=> true 
> school.students.build 
> school.students.size 
=> 2 
> school.valid? 
=> false 
> school.errors 
=> ... @messages={:students=>["too many"]} ... 

如果一切正常,就可以解决您的Rspec的代码。