我在测试一个相当简单的东西时遇到问题,即在数据库中不允许重复代码。
假设我有这个模型:
class Ticket < ActiveRecord::Base
attr_accessible :code, :series, :sec_code
validates_uniqueness_of :code, scope:[:series,:sec_code]
before_validation :generate_codes, on: :create
private
def generate_codes
self.code=rand.to_s[2..9] #-> 8 digit code
self.sec_code=rand.to_s[2..4] #-> 2 digit security code
self.series=('A'..'Z').to_a.sample #-> one character series
end
end
然后,我想以这种方式测试唯一性验证是否有效:
require 'spec_helper'
describe Ticket do
before do
@ticket=Ticket.create
end
subject{@ticket}
it{ should respond_to(:code)}
...
describe ", duplicate codes" do
before do
[email protected]
#Here lays the problem since this calls `generate_codes`
#before saving, so it ends up not being a duplicate!
dup_ticket.save #<---
end
it{ should_not be_valid}
end
end
我正在考虑使用after_initialize
,但是每次实例化对象时都调用此方法,即从数据库中提取对象后,这是不希望的。我想知道,为什么generate_codes
即使on: :create
在过滤器回调中有一个调用?
受jklina答案/评论的启发,我发现update_attribute
在这种情况下使用帮助,并且可以在不触发验证之前回调的情况下更新字段。因此测试变成:
require 'spec_helper'
describe Ticket do
before do
@ticket=Ticket.create
end
subject{@ticket}
it{ should respond_to(:code)}
...
describe ", duplicate codes" do
before do
[email protected]
dup_ticket.update_attribute(:code, @ticket.code)
dup_ticket.update_attribute(:sec_code, @ticket.sec_code)
dup_ticket.update_attribute(:series, @ticket.series)
end
it{ should_not be_valid}
end
end
因此反映了相同的值code
,sec_code
和series
在所述的ActiveRecord表。测试完成了预期的工作。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句