Everyday Rails - 3日目
P.44 まで。
FactoryGirlのファイルは、application.rbに以下設定が無くても、設定したのと同じ場所に作成される。
g.fixture_replacement :factory_girl, dir: 'spec/factories'
factoryファイルはrakeコマンドで作成できる。
また、ディレクトリ掘るとプロンプトが長くなったので改行した。色つけはしてない。
FactoryGirl.define do factory :contact do firstname { Faker::Name.first_name } lastname { Faker::Name.last_name } email { Faker::Internet.email } after(:build) do |contact| %W(home_phone work_phone mobile_phone).each do |phone| contact.phones << build(:phone, phone_type: phone, contact: contact) end end end end
associationは記述しなくてもよい。
FactoryGirl.define do factory :phone do contact phone { Faker::PhoneNumber.phone_number } factory :home_phone do phone_type 'home' end factory :work_phone do phone_type 'work' end factory :mobile_phone do phone_type 'mobile' end end end
FactoryGirlを使ってContact specを書き直すと以下のようになる。
require 'rails_helper' describe Contact, type: :model do it "has a valid factory" do expect(build(:contact)).to be_valid end it "has three phone numbers" do expect(create(:contact).phones.count).to eq 3 end it "is invalid without a firstname" do contact = build(:contact, firstname: nil) contact.valid? expect(contact.errors[:firstname]).to include("can't be blank") end it "is invalid without a lastname" do contact = build(:contact, lastname: nil) contact.valid? expect(contact.errors[:lastname]).to include("can't be blank") end it "is invalid without an email address" do contact = build(:contact, email: nil) contact.valid? expect(contact.errors[:email]).to include("can't be blank") end it "is invalid with a duplicate email address" do email = 'tester@example.com' create(:contact, email: email) contact = build(:contact, email: email) contact.valid? expect(contact.errors[:email]).to include("has already been taken") end it "returns a contact's full name as a string" do contact = build(:contact, firstname: 'John', lastname: 'Doe') expect(contact.name).to eq "John Doe" end describe "filter last name by letters" do before do @smith = create( :contact, firstname: 'John', lastname: 'Smith', email: 'jsmith@example.com' ) @jones = create( :contact, firstname: 'Tim', lastname: 'Jones', email: 'tjones@example.com' ) @johnson = create( :contact, firstname: 'John', lastname: 'Johnson', email: 'jjohnson@example.com' ) end context "matching letters" do it "returns a sorted array of results that match" do expect(Contact.by_letter("J")).to eq [@johnson, @jones] end end context "non-matching letters" do it "omits results that do not match" do expect(Contact.by_letter("J")).not_to include @smith end end end end