Provided that I have a project factory
Factory.define :project do |p|
p.sequence(:title) { |n| \"project #{n} title\" }
p.sequence(:
Just call FactoryGirl.reload in your before/after callback. This is defined in the FactoryGirl codebase as:
module FactoryGirl
def self.reload
self.factories.clear
self.sequences.clear
self.traits.clear
self.find_definitions
end
end
Calling FactoryGirl.sequences.clear is not sufficient for some reason. Doing a full reload might have some overhead, but when I tried with/without the callback, my tests took around 30 seconds to run either way. Therefore the overhead is not enough to impact my workflow.
To reset particular sequence you can try
# spec/factories/schedule_positions.rb
FactoryGirl.define do
sequence :position do |n|
n
end
factory :schedule_position do
position
position_date Date.today
...
end
end
# spec/models/schedule_position.rb
require 'spec_helper'
describe SchedulePosition do
describe "Reposition" do
before(:each) do
nullify_position
FactoryGirl.create_list(:schedule_position, 10)
end
end
protected
def nullify_position
position = FactoryGirl.sequences.find(:position)
position.instance_variable_set :@value, FactoryGirl::Sequence::EnumeratorAdapter.new(1)
end
end
Had to ensure sequences are going from 1 to 8 and restart to 1 and so on. Implemented like this:
class FGCustomSequence
def initialize(max)
@marker, @max = 1, max
end
def next
@marker = (@marker >= @max ? 1 : (@marker + 1))
end
def peek
@marker.to_s
end
end
FactoryGirl.define do
factory :image do
sequence(:picture, FGCustomSequence.new(8)) { |n| "image#{n.to_s}.png" }
end
end
The doc says "The value just needs to support the #next
method." But to keep you CustomSequence object going through it needs to support #peek
method too. Lastly I don't know how long this will work because it kind of hack into FactoryGirl internals, when they make a change this may fail to work properly