2015-02-26 2 views
2

Использование Rspec и FactoryGirl, если у меня есть фабрика, которая автоматически устанавливает значение trait с использованием последовательности и в некоторых спецификациях, если я явно задал этот признак, с достаточно большим набором тестов, иногда случайные функции завершатьсяПроверки уникальности Rspec/FactoryGirl в большом наборе тестов

Validation failed: uniq_id has already been taken 

завод определяется следующим образом:

factory :user { sequence(:uniq_id) {|n| n + 1000} } 

Я предполагаю, что это проверка терпит неудачу, потому что в одном месте в моем наборе тестов, я произвожу пользователя, как это:

create(:user, uniq_id: 5555) 

И поскольку предположительно фабричная девушка генерирует более 4,555 пользователей по сравнению с набором, проверка не выполняется?

Я пытаюсь избежать этой проблемы, просто повернув uniq_id на 55555 (большее количество), поэтому никаких помех нет. Но есть ли лучшее решение? Мой spec_helper включает в себя эти соответствующие биты:

config.use_transactional_fixtures = true 

config.after(:all) do 
    DatabaseCleaner.clean_with(:truncation) 
end 
+1

Я думаю, что вы можете решить свою проблему на заводских обратных вызовах. Например, вы можете проверить значение уникальности в 'after (: build)' обратном вызове, и если у другого пользователя с таким значением существует триггер 'sequence' снова. – gotva

+0

@gotva это звучит как отличное решение. Можете ли вы разместить ответ и с примером кода для 'after (: build)'? Я не уверен, как использовать последовательность в блоке, и их документы не дают понять. – mehulkar

+0

@gotova выяснил это на самом деле, и это сработало красиво. Спасибо! Добавьте в качестве ответа, чтобы я мог принять и дать вам все очки. – mehulkar

ответ

1

Я был в состоянии решить мою проблему, как это в моем заводе (основано на @ gotva-х внушения в вопросе комментариев).

factory :user do 
    sequence(:uniq_id) { |n| n + 1000 } 
    # increment again if somehow invalid 
    after(:build) do |obj| 
    if !obj.valid? && obj.errors.keys.include?(:uniq_id) 
     obj.uniq_id +=1 
    end 
    end 
end 
1

Это происходит со мной иногда. Я не нашел никаких объяснений, но это происходит только с большим набором данных. Я позволил кому-то найти объяснение!

Когда это происходит, вы можете объявить атрибут как это (здесь приведен пример использования faker камень):

FactoryGirl.define do 
    factory :user do 
    login do 
     # first attempt 
     l = Faker::Internet.user_name 
     while User.exists?(:login => l) do 
     # Here is a loop forcing validation 
     l = Faker::Internet.user_name 
     end 
     l # return login 
    end 
    end 
end 
Смежные вопросы