How to Reset a Factory_Girl Sequence

How can I reset a factory_girl sequence?

After tracing my way through the source code, I have finally come up with a solution for this. If you're using factory_girl 1.3.2 (which was the latest release at the time I am writing this), you can add the following code to the top of your factories.rb file:

class Factory  
def self.reset_sequences
Factory.factories.each do |name, factory|
factory.sequences.each do |name, sequence|
sequence.reset
end
end
end

def sequences
@sequences
end

def sequence(name, &block)
s = Sequence.new(&block)

@sequences ||= {}
@sequences[name] = s

add_attribute(name) { s.next }
end

def reset_sequence(name)
@sequences[name].reset
end

class Sequence
def reset
@value = 0
end
end
end

Then, in Cucumber's env.rb, simply add:

After do
Factory.reset_sequences
end

I'd assume if you run into the same problem in your rspec tests, you could use rspecs after :each method.

At the moment, this approach only takes into consideration sequences defined within a factory, such as:

Factory.define :specialty do |f|
f.sequence(:title) { |n| "Test Specialty #{n}"}
f.sequence(:permalink) { |n| "permalink#{n}" }
end

I have not yet written the code to handle: Factory.sequence...

avoid factorygirl repeate the number when run second time in cucumber

I solve this problem after replace this code

def create_accounts n=1
create_subscription
n.times do |r|
r += 1
FactoryGirl.create(:account, subscription_ids: @sub.id.to_s, name: "Test Account#{r}")
end
end

Updated

I am using cucumber-> capybara -> selenium

Reset the factory girl sequence

add this code in spec->support->reset.rb

module FactoryGirl
def self.reload
self.factories.clear
self.sequences.clear
self.traits.clear
self.find_definitions
end
end

Add this in env.rb

After do 
FactoryGirl.reload
end

Factory Girl sequences not incrementing

That works, bit it will mean that you can't override the name anywhere in the specs, because the after build hook will always run and overwrite any name.

The reason your original example doesn't work is that you're invoking the sequence when the factory is defined, rather than when the factory is run. You can provide a block to attribute definitions which will be invoked every time the factory runs. This way, you get a chance to generate a value for each instance, rather than generating one value for all instances. This is most frequently used for sequences and times.

You can fix your original example with this snippet:

sequence :vessel_name do |n|
"TK42#{n}"
end

factory :vessel do
name { generate(:vessel_name) }
vessel_type 'fermenter'
volume_scalar 100.0
volume_units 'bbl'
end

If all names can be generated with the same format, you could also leave out the value entirely by renaming your sequence:

sequence :name do |n|
"TK42#{n}"
end

factory :vessel do
name
vessel_type 'fermenter'
volume_scalar 100.0
volume_units 'bbl'
end

However, that won't work if you need different name formats for different factories.

Rails: Factory Girl failing to sequence

Your issue isn't with factory girl. When instantiating "user" you need to do it from inside a before block so that a new user gets created for each test being run. The user variable should also be an instance variable (i.e. prefixed with @)

require 'spec_helper'

describe User do

describe "test user factory is correct" do

before(:each) do
@user = Factory(:user)
end

it "should have an email ending in example.com" do
@user.email.should match "test2@example.com"
end

it "should have a password of foobar" do
@user.password.should == 'foobar'
end

it "should have a password confirmation field of foobar" do
@user.password_confirmation.should == 'foobar'
end

end

end

Using multiple sequence in Factory-girl

Try this

   FactoryGirl.define do
sequence :email do |n|
"email#{n}@factory.com"
end

sequence :username do |n|
"testuser#{n}"
end

factory :user do
username
email
password "secret"
password_confirmation "secret"
role "1"
end

end

Custom range with FactoryGirl sequence

You have to pass an object that responds to next, e.g. an enumerator:

FactoryGirl.define do
factory :user do
sequence(:email, (50..60).cycle) { |n| "user_#{n}@example.com" }
end
end

FactoryGirl.build(:user) #=> <#User @email="user_50@example.com">
FactoryGirl.build(:user) #=> <#User @email="user_51@example.com">
FactoryGirl.build(:user) #=> <#User @email="user_52@example.com">
# ...
FactoryGirl.build(:user) #=> <#User @email="user_59@example.com">
FactoryGirl.build(:user) #=> <#User @email="user_60@example.com">
# `cycle` will start over:
FactoryGirl.build(:user) #=> <#User @email="user_50@example.com">


Related Topics



Leave a reply



Submit