I am new to Rspec and FactoryGirl for testing ROR applications. I am trying to test a model class method add_product(product_id)
and it keeps failing though it works when i try the same on the browser. here is the code for the model:
class Cart < ActiveRecord::Base
has_many :line_items, inverse_of: :cart
def add_product(product_id)
current_item = line_items.find_by_product_id(product_id)
if current_item
current_item.quantity += 1
else
current_item = line_items.build(:product_id => product_id)
end
current_item
end
end
Here is the failing spec for the cart model:
describe Cart do
before(:each) do
@cart = FactoryGirl.create(:cart)
@product = FactoryGirl.create(:product)
@line_item = FactoryGirl.create(:line_item, product_id: @product.id, cart_id: @cart.id)
end
it 'increases the quantity of line_item when a similar product is added' do
lambda {@cart.add_product(@product.id)}.should change {@line_item.quantity}.by(1)
end
end
This fails and i get this message from Rspec Failure/Error: lambda {@cart.add_product(@product.id)}.should change {@line_item.quantity}.by(1)
result should have been changed by 1, but was changed by 0
The quantity is being updated, but you're never persisting the data. So the data is never hitting the database and the test is never going to see a change. You'll run into the same problem with .build where it is not persisted until you explicitly say so. You can change this by doing.
class Cart < ActiveRecord::Base
has_many :line_items, inverse_of: :cart
def add_product(product_id)
current_item = line_items.find_by_product_id(product_id)
if current_item
current_item.quantity += 1
current_item.save
else
current_item = line_items.create(:product_id => product_id)
end
current_item
end
end