Rails 3 + Rspec 2: проверка не удалась: электронная почта уже была занята - PullRequest
8 голосов
/ 09 апреля 2011

У меня 2 модели, User и Bucket.User has_many Buckets и Bucket belongs_to a User.

В factories.rb у меня есть:

Factory.define :user do |user|
  user.email  "teste@test.com"
  user.password               "foobar"
  user.password_confirmation  "foobar"
end


Factory.sequence :email do |n| 
  "person-#{n}@example.com"
end

Factory.define :bucket do |bucket|
  bucket.email        "user@example.com"
  bucket.confirmation false
  bucket.association :user
end

, и у меня есть login_userмодуль выглядит следующим образом:

def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      @user = Factory.create(:user)
      #@user.confirm!
      sign_in @user
    end
  end

Я использую Spork и Watch, и мой Buckets_controller_spec.rb так же прост, как:

describe "User authenticated: " do

   login_user  

   @bucket = Factory(:bucket)

   it "should get index" do
     get 'index'
     response.should be_success
   end
...
end

Ошибка всегда одинакова:

Failures:

  1) BucketsController User authenticated: should get index
     Failure/Error: Unable to find matching line from backtrace
     ActiveRecord::RecordInvalid:
       Validation failed: Email has already been taken
     # ./lib/controller_macros.rb:12:in `block in login_user'

И это происходит только тогда, когда у меня есть Factory(:bucket).Логин работает нормально, когда я не добавляю Factory(:bucket).

Это всегда одна и та же ошибка.Я попытался добавить :email => Factory.next(:email) к пользователю, но безуспешно.

Редактировать:

В rails c test:

ruby-1.9.2-p180 :019 > bucket = Factory(:bucket, :email => "hello@hello.com")
    ActiveRecord::RecordInvalid: Validation failed: Email has already been taken

    ruby-1.9.2-p180 :018 >   Bucket.create(:email => "hello@hello.com")
     => #<Bucket id: 2, email: "hello@hello.com", confirmation: nil, created_at: "2011-04-08 21:59:12", updated_at: "2011-04-08 21:59:12", user_id: nil> 

Редактировать 2:

Я обнаружил, что ошибка в ассоциации, однако я не знаю, как ее исправить.

  bucket.association :user

Ответы [ 3 ]

6 голосов
/ 12 апреля 2011

Когда вы определяете фабрику с ассоциацией, вам нужно дать фабрике объект, с которым вы будете ассоциироваться, когда вы используете фабрику.

Это должно работать:

describe "User authenticated: " do
  login_user
  @bucket = Factory(:bucket, :user => @user)

  it "should get index" do
    get 'index'
    response.should be_success
  end
end

Таким образом, Factorygirl знает, как создать ведро, связанное с @ user.

5 голосов
/ 09 апреля 2011

Попробуйте это на своей фабрике пользователей:

Factory.define :user do |f|
  f.sequence(:email) { |n| "test#{n}@example.com" }
  ...
end

Я думаю, что это, вероятно, ваша проблема.Когда вы используете f.email = "anyvalue", оно будет использовать это значение каждый раз.Я вижу, что вы пытались создать последовательность в следующем блоке, но я не уверен, что последовательность используется.

ТАКЖЕ - имейте в виду, что если вы получаете тесты, прерванные сбоем или чем-то, иногда фиктивнымтестовые данные могут остаться в вашей тестовой БД вместо отката.

Самое первое, что я пытаюсь сделать, если что-то сработало один раз, а затем прекращаю работать, это сбрасываю тестовую базу данных.Это все очистит.

Если это не сработает, дайте мне знать, и я еще раз посмотрю!

0 голосов
/ 12 сентября 2012

Если кто-то недавно получил это с вашими взглядами. Попробуйте использовать Database Cleaner .

Для получения дополнительной информации: RailsTutorial - глава 8.4.3 - Тестовая база данных не очищается после добавления пользователя в интеграционном тесте

...