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
How to Write an Rspec Test for a Ruby Method That Contains "Gets.Chomp"
Undefined Method 'Name' for "Actionmailer":String
Cocoon Add Association, How to Limit Number of Associations
Missing File in Gem After Build
How to Get Long Filename from Argv
Rails Routes: Wrong Singular for Resources
Wrapping Text into Lines at Word Boundaries
How Does Activerecord Define Methods Compared to Attr_Accessor
How to Convert JSON to a Hash, Search for and Change a Value
Writing an Activerecord Adapter
How to Run Ruby on Rails Applications on a Windows Box
How to Memoize a Method That May Return True, False, or Nil in Ruby
Remove Subdomain from String in Ruby
How to Print Stdout Immediately
Why Ruby Inject Method Cannot Sum Up String Lengths Without Initial Value