Witam.
Mam problem z pisaniem testów integracyjnych. Mianowicie w momencie kiedy chcę stworzyć obiekt o złożonym kluczu pierwotnym rzuca mi wyjątkiem.
Treść wyjątku
Failure/Error: FactoryGirl.create(:data_area, data_set: @data_set) #, synchronization_report: @data_set.synchronization_report)
ActiveRecord::RecordInvalid:
Validation failed: Data set can't be blank
Migracja
class CreateDataAreas < ActiveRecord::Migration
def change
create_table :data_areas do |t|
t.string :configuration_id, null: false, limit: 100
t.integer :data_set_id, null: true
t.integer :synchronization_report_id, null: true
t.string :status, null: false, limit: 20
t.string :error_type, null: true, limit: 100
t.string :error_text, null: true
t.string :sql, null: true
t.integer :records_files_processed, null: false
t.timestamps null: false
end
execute "ALTER TABLE data_areas DROP CONSTRAINT data_areas_pkey;"
execute "ALTER TABLE data_areas ADD CONSTRAINT data_areas_pkey PRIMARY KEY (id, data_set_id, synchronization_report_id);"
execute "ALTER TABLE data_areas ADD FOREIGN KEY (data_set_id, synchronization_report_id) REFERENCES data_sets(id, synchronization_report_id);"
end
end
Model
class SynchronizationReport::DataSet < ActiveRecord::Base
self.table_name = :data_sets
self.primary_keys = :id, :synchronization_report_id
belongs_to :synchronization_report
has_many :data_areas, class_name: SynchronizationReport::DataArea, dependent: :delete_all
validates_presence_of :synchronization_report_id, :configuration_id, :synch_time
validates_length_of :configuration_id, in: 2..100
end
class SynchronizationReport::DataArea < ActiveRecord::Base
self.table_name = :data_areas
self.primary_keys = :id, :data_set_id, :synchronization_report_id
belongs_to :data_set, foreign_key: [:data_set_id, :synchronization_report_id]
belongs_to :synchronization_report
validates_inclusion_of :status, in: %w[imported import_failed exported export_failed]
validates_presence_of :configuration_id, :data_set_id, :synchronization_report_id, :status, :records_files_processed
validates_length_of :configuration_id, in: 3..100
validates_length_of :status, in: 3..20
validates_length_of :error_type, in: 3..100, allow_nil: true
end
Factory
FactoryGirl.define do
factory :data_area, class: SynchronizationReport::DataArea do |f|
f.configuration_id { Faker::Internet.password(rand(1..99), 100) }
f.data_set { FactoryGirl.build(:data_set) }
f.synchronization_report { FactoryGirl.build(:synchronization_report) }
f.status { %w[imported import_failed exported export_failed][rand(0..3)] }
f.records_files_processed { Faker::Number.between(1, 1000) }
end
end
Testy, w których wykorzytuję te Factory
RSpec.describe SynchronizationReport::DataSet, type: :model do
before(:all) do
synchronization_report = FactoryGirl.create(:synchronization_report)
@data_set = FactoryGirl.create(:data_set, synchronization_report: synchronization_report)
end
after(:all) do
synchronization_report = @data_set.synchronization_report
synch_agent = synchronization_report.synch_agent
synchronization_report.destroy
exchange_server = synch_agent.exchange_server
synch_agent.destroy
exchange_server.destroy
end
...
describe "data_areas relation" do
before(:all) do
(0...5).each do |i|
FactoryGirl.create(:data_area, data_set: @data_set, synchronization_report: @data_set.synchronization_report)
end
end
it { should have_many(:data_areas) }
it { expect( @data_set.data_areas.size ).to eq 5 }
end
end
Dodam, że jak wpiszę sobie binding.pry w pętli gdzie tworzę :data_area i sprawdzam zawartość bazy to obiekty data_set i synchronization_report są tam obecne.