Search code examples
ruby-on-railsrspecrspec-railsdestroy

Why doesn't this simple destroy method expectation work?


After doing some research here, and using Google I'm still confused as to why this simple spec isn't working:

describe CartsController do
  #stuff omitted...
  describe "carts#destroy" do
    it "destroys the requested cart" do
      cart = FactoryGirl.create(:cart)
      puts "Cart count = #{Cart.count}"
      expect {
        delete :destroy, :id => cart.id
      }.to change(Cart, :count).by(-1)
    end
  end
#stuff omitted...
end

Here's the CartsController's action:

class CartsController < ApplicationController

  def destroy
    @cart = current_cart
    @cart.destroy
    session[:cart_id] = nil

    respond_to do |format|
      format.html { redirect_to(store_url, :notice => 'Your cart is currently empty') }
      format.json { head :ok }
    end
  end

end

And last but not least, the error I'm getting:

Cart count = 1
F

Failures:

  1) CartsController carts#destroy destroys the requested cart
     Failure/Error: expect {
       count should have been changed by -1, but was changed by 0
     # ./spec/controllers/carts_controller_spec.rb:146:in `block (3 levels) in <top (required)>'

Finished in 6.68 seconds
1 example, 1 failure

I'm new to rspec tests, however, As far as I understand my destroy spec is very straightforward, and it should perform as expected. I have no idea of what I'm doing wrong..

Please help me, Thankful as always,

EDIT.. here's the current_cart method:

def current_cart
  Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
  cart = Cart.create
  session[:cart_id] = cart.id
  cart
end

Solution

  • According to what you provide, I guess you should simply add:

    session[:cart_id] = cart.id
    

    before your expect block.

    Why? It seems you're not really using the id passed in the url but the value stored in session. But to be sure, you should provide your current_cart method.