Reputation: 5251
I am learning to do tests using Rails testing tools, mainly: rspec, factory_girl, shoulda, and faker
gems.
I want to test has_one
and belongs_to
associations. I have user.rb
(with name
) and address.rb
(with street
, city
, and user_id
) models.
I am trying to figure out how to create fake associations using fakers. I want to create a fake street and associate it with a fake user, but I can't figure out how to do it on spec/factories/addresses.rb
This is what I currently have:
FactoryGirl.define do
factory :address do
street {Faker::Address.street_address}
city {Faker::Address.city}
#Creates fake user and use that user's id for user_id)#
user = build(:user, name: "Joe", id: 2)
user_id {user.id}
end
end
This is the spec/models/address_spec.rb
require 'rails_helper'
RSpec.describe Address, type: :model do
it "has a valid factory" do
address = build(:address)
expect(address).to be_valid
end
it {should belong_to(:user)}
end
When I run it, it shows add_attribute': wrong number of arguments (given 3, expected 1..2) (ArgumentError)
error. I tried removing the id on the argument and just did user = build(:user, name: "Joe")
but the same error message still shows.
The test passes if I don't include the user lines on addresses
factory. I confirmed that address has belongs_to :user
and user has has_one :address
.
Is it possible to generate fake association and associate address to a fake user.id
? I would like to test Address
's user_id
as well.
Edit - following are the related factories and models:
Factories
addresses.rb
FactoryGirl.define do
factory :address do
street {Faker::Address.street_address}
city {Faker::Address.city}
user
end
end
users.rb
FactoryGirl.define do
factory :user do
name {Faker::Name.name}
end
end
spec/models
address_spec.rb
require 'rails_helper'
RSpec.describe Address, type: :model do
it "has a valid factory" do
association user
specific_user = build(:user, name: 'Joe')
address = build(:address, specific_user)
expect(address).to be_valid
end
it {should belong_to(:user)}
end
Error running address_spec.rb
NameError:
undefined local variable or method `user' for #<RSpec::ExampleGroups::Address:0x00000001a94b00>
# ./spec/models/addres
Upvotes: 1
Views: 1293
Reputation: 2478
I think the way you build association is incorrect. See https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#associations.
If you want a more specific associated user eg name: Joe, id: 2, it's probably better to do it in spec.
Factory:
FactoryGirl.define do
factory :address do
street {Faker::Address.street_address}
city {Faker::Address.city}
user
end
end
Spec:
it "has a valid factory" do
specific_user = build(:user, name: 'Joe')
address = build(:address, specific_user)
expect(address).to be_valid
end
Upvotes: 2