我有很多这样的关系模型:
class Physician < ApplicationRecord
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ApplicationRecord
belongs_to :physician
belongs_to :patient
end
class Patient < ApplicationRecord
has_many :appointments
has_many :physicians, through: :appointments
end
我需要创建一位有很多患者的医生,对吧? 所以我的测试:
let!(:physician) { create(:physician) }
let!(:patients) { create_list(:patients, 2) }
我这样做了:
before { physician.patients << patients }
我想用这个
来测试生成的jsonexpect(physician.as_json).to eq({
"id" => physician.id,
"name" => physician.name,
"patients" => physician.patients
})
我希望它会通过,但由于#<ActiveRecord::Associations::CollectionProxy>
我使用binding.pry
进行了检查:
physician.patients == patients
结果是true
你介意帮助我,我在这里错过了什么吗?
答案 0 :(得分:1)
要将医生和患者联系起来,只需将密钥传递给create_list
:
let!(:patients) { create_list(:patients, 2, physician: physician ) }
或者您可以将其声明为:
let(:physician) { create(:physician, patients: build_list(patients: 2)) }
但@TomLord提到的测试本身仍然存在问题。您需要测试生成的哈希 - 因为包括关联将导致它转换为序列化哈希:
{
"id" => 1,
"name" => "Dr Suess",
"patients" => [
{
"id" => 1,
"name" => "The Cat in The Hat"
},
{
"id" => 2,
"name" => "The Grinch"
},
]
}
使用eq
测试确切的输出并不是最佳的,因为序列化的每次更改都会破坏测试。相反,您可以使用include
matcher来指定必须存在的内容:
describe '#as_json' do
let!(:physician) { create(:physician) }
let!(:patients) { create_list(:patients, 2) }
subject(:serialized) { physician.as_json }
it { should include({
"id" => physician.id,
"name" => physician.name
}) }
it "includes the patients" do
expect(serialized["patients"].length).to eq patients.length
expect(serialized["patients"]).to include patients.first.as_json
expect(serialized["patients"]).to include patients.last.as_json
end
end
除非您已覆盖as_json
方法,否则此规范应失败,因为您需要明确包含与physician.as_json(include: :patients)
的关联。