2013-03-14 44 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的代碼。