Reputation: 8091
Note: A business has many catalogs and has products, and a catalog has many products. The associations are properly defined and they are working in the application front end. But I can't make this test pass. I am using friendly_id so you will see me using @model.slug on some of the find methods
I am trying this test out:
describe "GET 'show'" do
before do
@business = FactoryGirl.create(:business)
@catalog = FactoryGirl.create(:catalog, :business=>@business)
@product1 = FactoryGirl.create(:product, :business=>@business, :catalog=>@catalog)
@product2 = FactoryGirl.create(:product, :business=>@business, :catalog=>@catalog)
end
def do_show
get :show, :business_id=>@business.slug, :id=>@catalog.slug
end
it "should show products" do
@catalog.should_receive(:products).and_return([@product1, @product2])
do_show
end
end
with this factory (note that a business and catalog factory is define somewhere else, and they are associations):
FactoryGirl.define do
sequence :name do |n|
"product#{n}"
end
sequence :description do |n|
"This is description #{n}"
end
factory :product do
name
description
business
catalog
end
end
with this show action:
def show
@business = Business.find(params[:business_id])
@catalog = @business.catalogs.find(params[:id])
@products = @catalog.products.all
respond_with(@business, @catalog)
end
but I am getting this error:
CatalogsController GET 'show' should show products
Failure/Error: @catalog.should_receive(:products).and_return([@product1, @product2])
(#<Catalog:0x000001016185d0>).products(any args)
expected: 1 time
received: 0 times
# ./spec/controllers/catalogs_controller_spec.rb:36:in `block (3 levels) in <top (required)>'
furthermore, this code block will also indicate that Business model has not received the find method:
Business.should_receive(:find).with(@business.slug).and_return(@business)
Upvotes: 0
Views: 1440
Reputation: 6034
The problem here is that the @catalog instance variable you set up in the spec is not the same as the @catalog instance variable in the controller.
@catalog in the spec will never receive any messages sent to @catalog in the controller.
What you need to do instead is to change this in your spec:
@catalog.should_receive(:products).and_return([@product1, @product2])
to
Catalog.any_instance.should_receive(:products).and_return([@product1, @product2])
Check out the RSpec documentation on any_instance.should_receive here: https://www.relishapp.com/rspec/rspec-mocks/v/2-6/docs/message-expectations/expect-a-message-on-any-instance-of-a-class
Upvotes: 1