How can I reset a factory_girl sequence?

后端 未结 9 1928
梦毁少年i
梦毁少年i 2020-12-16 10:17

Provided that I have a project factory

Factory.define :project do |p|
  p.sequence(:title)    { |n| \"project #{n} title\"                  }
  p.sequence(:         


        
相关标签:
9条回答
  • 2020-12-16 11:12

    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.

    0 讨论(0)
  • 2020-12-16 11:16

    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
    
    0 讨论(0)
  • 2020-12-16 11:19

    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

    0 讨论(0)
提交回复
热议问题