2011-04-06 40 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

相关问题