Я правильно использую фабрики? - PullRequest
4 голосов
/ 05 августа 2011

Это мои текущие настройки тестирования:

# spec/factories.rb
require 'factory_girl'

FactoryGirl.define do
  # Roles

  factory :user_role, :class => Role do
    name 'User'
  end

  # Users
  factory :user, :class => User do
    sequence(:email) {|n| "email#{n}@example.com" }
    password 'password'
    password_confirmation 'password'
    name 'Yuri Userington'
    roles { |a| [a.association(:user_role)] }
  end

  # Instruments
  factory :instrument, :class => Instrument do
    title "Doobie Doo Instrument Title"
    is_valid true
    association :user, :factory => :user
  end

  # Sequences
  sequence :email do
    "email#{n}@factory.com"
  end

end

# spec/controllers/instruments_controller_spec.rb
require 'spec_helper'

describe InstrumentsController do

  before (:each) do
    @instrument = FactoryGirl.create(:instrument)
    @attr = FactoryGirl.attributes_for(:instrument)
    @user = FactoryGirl.create(:user)
  end

  describe "GET index" do
    it "assigns all instruments as @instruments" do
      instrument = Instrument.new(@attr)
      instrument.user = @user 
      instrument.save!
      get :index
      assigns(:instruments).should eq([instrument])
    end 
  end

end

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

Failures:

  1) InstrumentsController GET index assigns all instruments as @instruments
     Failure/Error: @instrument = FactoryGirl.create(:instrument)
     ActiveRecord::RecordNotFound:
       Couldn't find Role with id=2
     # ./app/models/user.rb:21:in `assign_role_after_sign_up'
     # ./spec/controllers/instruments_controller_spec.rb:24:in `block (2 levels) in <top (required)>'

Исходя из этого, мне кажется, что вызов ассоциаций ролей в моем: фабрика пользователей НЕ вызывается - что я здесь не так делаю? Я использую это совершенно неправильно?

спасибо !!

Ответы [ 2 ]

4 голосов
/ 06 августа 2011

Здесь есть что сказать.Сравните ваш код со следующим, чтобы увидеть, сколько строк или слов было удалено.

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

  # Roles
  factory :user_role, :class => Role do
    name 'User'
  end

  # Users
  factory :user do
    email
    password 'password'
    password_confirmation 'password'
    name 'Yuri Userington'
    roles { |user| [Factory(:user_role)] } #many to many
   end

  # Instruments
  factory :instrument, :class => Instrument do
    title "Doobie Doo Instrument Title"
    is_valid true
    association :user #one-to-one or one-to-many
  end

end

И в ваших тестах:

describe InstrumentsController do

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

  describe "GET index" do
    it "assigns all instruments as @instruments" do
      instrument = Factory(:instrument, :user => @user)
      get :index
      assigns(:instruments).should eq([instrument])
    end 
  end

end

Более того:

  • Я лично предпочитаю тестировать контроллер с макетами и заглушками

  • Я использую let вместо переменных экземпляра и before_filter

2 голосов
/ 05 августа 2011

У меня были похожие проблемы, и я использовал обратный вызов для назначения ролей следующим образом:

Factory.define :user_with_admin_role, :parent => :user do |user|
  user.after_create {|instance| instance.roles << Factory(:admin_role) }
end

Так что я думаю, что вы должны быть в состоянии сделать что-то похожее на это:

# Users
factory :user, :class => User do
  sequence(:email) {|n| "email#{n}@example.com" }
  password 'password'
  password_confirmation 'password'
  name 'Yuri Userington'
  after_create {|user| user.roles << Factory(:user_role) }
end

Это полностью не проверено, так что вам может понадобиться настроить все вокруг.

...