Неудачный тест контроллера Rails 4 - ActiveRecord :: AssociationTypeMismatch?

Я создаю приложение Rails (4.1.8) с Postgres (0.18.3), Rspec (3.1.0) и FactoryGirl (4.5.0). Мне нужна помощь в устранении неполадок при тестировании контроллера, которое вызывает ошибку Active Record :: AssociationTypeMismatch, вызванную объектом FactoryGirl.

Вот мое действие индекса контроллера фитнес-целей:

def index
  @fitness_goals = @member.fitness_goals.order(:start_date)    
end

Это моя настройка и проверка действия индекса контроллера фитнес-целей (fitness_goals_controller_spec.rb):

RSpec.describe FitnessGoalsController, :type => :controller do

let(:member_attributes) { { 

  "first_name" => 'Joe',
  "last_name" => 'Smith',
  "sex" => 'Male', 
  "age" => 30,
  "height" => 69,
  "weight" => 187,
  "goal" => ["Lose Fat"],
  "start_date" => Date.current    
  }
 }  

before :each do
  @request.env["devise.mapping"] = Devise.mappings[:user]
  @user = FactoryGirl.create(:user)
  sign_in @user

  @member = @user.build_member member_attributes
  @member.save

  @fitness_goal = FactoryGirl.create(:fitness_goal, member: @member)
  @fitness_goal_attributes = FactoryGirl.build(:fitness_goal).attributes
  @fitness_goal_invalid_attributes = FactoryGirl.build(:fitness_goal, timeframe_id: nil).attributes
  @fitness_goal_update_attributes = FactoryGirl.build(:fitness_goal).attributes
  @fitness_goal_update_invalid_attributes = FactoryGirl.build(:fitness_goal, timeframe_id: nil).attributes
end

describe "GET index" do
  it "assigns all fitness goals as @member.fitness_goals" do
    get :index, { :member_id => @member  }
    expect(assigns(:fitness_goals)).to eq(@member.reload.fitness_goals)
  end
end

Ошибка rspec и трассировка:

1) FitnessGoalsController GET index assigns all fitness goals as @member.fitness_goals
 Failure/Error: @fitness_goal = FactoryGirl.create(:fitness_goal, member: @member)
 ActiveRecord::AssociationTypeMismatch:
   Target(#62887900) expected, got String(#8489780)
 # .rvm/gems/ruby-2.1.5/gems/activerecord-4.1.8/lib/active_record/associations/association.rb:216:in `raise_on_type_mismatch!'
 # .rvm/gems/ruby-2.1.5/gems/activerecord-4.1.8/lib/active_record/associations/collection_association.rb:356:in `block in replace'
 # .rvm/gems/ruby-2.1.5/gems/activerecord-4.1.8/lib/active_record/associations/collection_association.rb:356:in `each'
 # .rvm/gems/ruby-2.1.5/gems/activerecord-4.1.8/lib/active_record/associations/collection_association.rb:356:in `replace'
 # .rvm/gems/ruby-2.1.5/gems/activerecord-4.1.8/lib/active_record/associations/collection_association.rb:41:in `writer'
 # .rvm/gems/ruby-2.1.5/gems/activerecord-4.1.8/lib/active_record/associations/builder/association.rb:118:in `targets='
 # .rvm/gems/ruby-2.1.5/gems/factory_girl-4.5.0/lib/factory_girl/attribute_assigner.rb:16:in `public_send'
 # .rvm/gems/ruby-2.1.5/gems/factory_girl-4.5.0/lib/factory_girl/attribute_assigner.rb:16:in `block (2 levels) in object'
 # .rvm/gems/ruby-2.1.5/gems/factory_girl-4.5.0/lib/factory_girl/attribute_assigner.rb:15:in `each'
 # .rvm/gems/ruby-2.1.5/gems/factory_girl-4.5.0/lib/factory_girl/attribute_assigner.rb:15:in `block in object'
 # .rvm/gems/ruby-2.1.5/gems/factory_girl-4.5.0/lib/factory_girl/attribute_assigner.rb:14:in `tap'
 # .rvm/gems/ruby-2.1.5/gems/factory_girl-4.5.0/lib/factory_girl/attribute_assigner.rb:14:in `object'
 # .rvm/gems/ruby-2.1.5/gems/factory_girl-4.5.0/lib/factory_girl/evaluation.rb:12:in `object'
 # .rvm/gems/ruby-2.1.5/gems/factory_girl-4.5.0/lib/factory_girl/strategy/create.rb:9:in `result'
 # .rvm/gems/ruby-2.1.5/gems/factory_girl-4.5.0/lib/factory_girl/factory.rb:42:in `run'
 # .rvm/gems/ruby-2.1.5/gems/factory_girl-4.5.0/lib/factory_girl/factory_runner.rb:23:in `block in run'
 # .rvm/gems/ruby-2.1.5/gems/activesupport-4.1.8/lib/active_support/notifications.rb:161:in `instrument'
 # .rvm/gems/ruby-2.1.5/gems/factory_girl-4.5.0/lib/factory_girl/factory_runner.rb:22:in `run'
 # .rvm/gems/ruby-2.1.5/gems/factory_girl-4.5.0/lib/factory_girl/strategy_syntax_method_registrar.rb:20:in `block in define_singular_strategy_method'
 # ./spec/controllers/fitness_goals_controller_spec.rb:44:in `block (2 levels) in <top (required)>'

Ошибка ссылается на модель Target, ассоциацию has_and_belongs_to_many (HABTM) с моделью Fitness Goal: Target (# 62887900) ожидается, есть String (# 8489780)

Соответствующие модели:

class FitnessGoal < ActiveRecord::Base
  has_and_belongs_to_many :targets
end

class Target < ActiveRecord::Base   
  has_and_belongs_to_many :fitness_goals
end

Таблица соединений в схеме:

create_table "fitness_goals_targets", id: false, force: true do |t|
  t.integer "fitness_goal_id"
  t.integer "target_id"

конец

Параметры фитнес-целей:

def fitness_goal_params
  params.require(:fitness_goal).permit(:goal_list_id, :timeframe_id, :start_date, :end_date, { target_ids: [] }, { activity_ids: [] }, :notes, :member_id, :trainer_id)
end

Фабрика фитнес-целей:

FactoryGirl.define do
  factory :fitness_goal do
association :goal_list
association :timeframe
start_date Date.current
end_date Date.current + 30              
targets ["Lose Fat", "Reduce caloric intake by x%"]
activities ["Walk x steps a day", "Climb x floors a day", "Run x miles a day"]      
association :member
association :trainer
notes 'This is a sample note.'
  end
end

Что я делаю неправильно? Код приложения работает должным образом как в среде разработки, так и в производственной среде. Похоже, проблема где-то в моей настройке для объекта FactoryGirl. Реализация ассоциации HABTM - вот что сломало тест контроллера. Как мне исправить проблему и снова пройти тест контроллера? Спасибо за любую помощь!


person codeinspired    schedule 23.12.2015    source источник


Ответы (1)


Вам нужно изменить фабрику, чтобы передавать в эту ассоциацию целевые объекты, а не строки. Итак, вам нужно создать объекты Target (или найти их, если они уже существуют). Изменять

targets ["Lose Fat", "Reduce caloric intake by x%"]

to

targets { [create(:target, field: "Lose Fat"), create(:target, field: "Reduce caloric intake by x%")] }

Я использовал метку «поле», потому что я не уверен, как называется это поле, поэтому просто используйте его имя.

person odaata    schedule 23.12.2015