我遇到问题测试一个相当简单的事情,即在数据库中不允许的代码的重复性。跳过before_validation上::在测试中创建
比方说,我有这样的模式:
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
,但是每当对象被实例化时,即在从DB中提取之后,这就被调用,这是不期望的。 我想知道为什么generate_codes
即使在过滤器回调中有on: :create
也被调用?
我会尽力的,谢谢!尽管如果可能的话,我会*尽量避免嘲笑和剔除tbh。 :/ – lllllll
由于所有的代码似乎都可以访问,所以可以使用'dup_ticket.update_attributes(代码:@ ticket.code ...)'。这会保存记录并且不运行generate_codes命令,因为你似乎只在'create'上创建了它' – jklina
我也考虑过这个问题,但是我认为'save'会被调用,并且它确实没有帮助。然而!如果我使用'update_attribute'来代替回调,那么回调并不是“执行”的,这在最后还是有效的! – lllllll