Reputation: 1093
I had a class called listing and product:
class Listing
belongs_to :product
def item
@item ||= Product.find(product_id)
end
def url
"http://example.com/#{@item.pid}"
end
end
class Product
has_one :listing
attr_accessor :pid #returns an integer
end
in my spec file I create a listing object with factory girl and assign it a product. I tested it in previous specs and whenever I called:
@listing.item.id.should eq(@product.id)
It would pass.
However, I tried to call:
@product = FactoryGirl.create(:product)
@listing = FactoryGirl.create(:listing)
@product.listing = @listing
@listing.url.should eq("...")
And it could not call the url method on the listing class... How could I get this to pass but still make for a good test?
Upvotes: 0
Views: 86
Reputation: 2432
I'm confused why you created the item
method when you already have the belongs_to
association set up.
class Listing
belongs_to :product
def url
"http://example.com/#{product.pid}"
end
end
class Product
has_one :listing
attr_accessible :pid
end
# test setup
# you can define the association in the factory
FactoryGirl.define do
factory :listing do
association :product
end
factory :product do
pid 1234
end
end
# test
listing = FactoryGirl.create(:listing)
listing.url.should eq "http://example.com/1234"
Upvotes: 0
Reputation: 29389
In your Listing
model, the instance variable @item
only gets defined if the item
method is called, which doesn't happen in your test. As a result, when the url
method is called, @item
is nil and @item.pid
results in an undefined method error
as a result of sending pid
to nil
.
You can, however, change your @item.pid
reference in the url
method to be simply item.pid
and you'll be ok, as this will invoke the item
method.
While that explains the error you're getting, I can't really advise you on what a good test is because it's not clear what you are trying to accomplish in your application.
Upvotes: 2