2011-04-06 83 views
5

我有一個before_validation :do_something, :on => :create在我的一個模型。有沒有一種好方法在Rails中用':on`參數測試`before_validation`回調?

我想測試是否發生這種情況,並且不是發生在:save上。

有沒有對此進行測試(使用Rails 3,摩卡和早該)一個簡潔的方式,而不會做這樣的事情:

context 'A new User' do 
    # Setup, name test etc 
    @user.expects(:do_something) 
    @user.valid? 
end 

context 'An existing User' do 
    # Setup, name test etc 
    @user.expects(:do_something).never 
    @user.valid? 
end 

找不到早該API中的任何事情,這種感覺相當非幹...

任何想法?謝謝:)

+0

好的,如果你找到一個匹配器/寫一個或有人想出一個:before_validation,請務必使用這個簡單的技術從這[post](http://stackoverflow.com/questions/3134066/ shoulda-rspec-matchers-on-create/5372151#5372151)解決該問題:on => create。一個非常簡單的解決方案,使用「主題」塊。 – jake 2011-09-19 05:44:09

回答

9

我認爲你需要改變你的方法。您正在測試Rails正在工作,而不是您的代碼適用於這些測試。想想測試你的代碼吧。

舉例來說,如果我有這個相當空洞類:

class User 
    beore_validation :do_something, :on => :create 

    protected 

    def do_something 
    self.name = "#{firstname} #{lastname}" 
    end 
end 

我會實際測試這樣的:

describe User do 
    it 'should update name for a new record' do 
    @user = User.new(firstname: 'A', lastname: 'B') 
    @user.valid? 
    @user.name.should == 'A B' # Name has changed. 
    end 

    it 'should not update name for an old record' do 
    @user = User.create(firstname: 'A', lastname: 'B') 
    @user.firstname = 'C' 
    @user.lastname = 'D' 
    @user.valid? 
    @user.name.should == 'A B' # Name has not changed. 
    end 
end 
+0

儘管我完全同意您的上述說明,但您建議的解決方案可能不是最簡單的方法。從角度考慮,我不想測試:do_something方法本身。 (這可能是一個更復雜的調用的公共方法,可能會直接進行測試)但是我想測試這個確實在確認回調之前的位置。我認爲一些應用匹配者採用這種方法。 – jake 2011-09-19 05:14:08

+0

但是,如果:do_something是僅用於此目的的私有方法,我同意測試整體效果是否保存/或有效?是正確的路要走。如果您決定完全不使用回調方法,這也會使測試不會中斷。無論是哪種情況,重要的是不要嘗試測試框架。 – jake 2011-09-19 05:16:28

相關問題