0
votes

I am trying to write an rspec test for my destroy action of my user_stocks_controller but I get an error:

UserStocksController DELETE #destroy deletes stock Failure/Error: delete :destroy, params: { id: user_stock.id }

ActionController::UrlGenerationError: No route matches {:action=>"destroy", :controller=>"user_stocks", :id=>nil}

I have read that the problem exist because I didn't give id for stock. I was trying to change it on a multi different way but of my ideas wasn't right.

Here is my spec:

let(:user) { User.new(email: '[email protected]', password: 'password') }

  before do
    sign_in(user)
  end

 describe 'DELETE #destroy' do
    let(:stock) { Stock.new_from_lookup('GS') }
    let(:user_stock) { UserStock.create(user: user.id, stock: stock) }

    it 'deletes stock' do
      expect do
        delete :destroy, params: { id: user_stock.id }
      end.to change(UserStock, :count).by(-1)
      expect(response).to have_http_status(redirect)
      expect(flash[:notice]).to eq 'Stock successfully removed'
    end
  end

Destroy method in user_stocks_controller:

  def destroy
    stock = Stock.find(params[:id])
    @user_stock = UserStock.where(user_id: current_user.id, stock_id: stock.id).first
    @user_stock.destroy!
    flash[:notice] = 'Stock successfully removed'
    redirect_to my_portfolio_path
  end

Why is not detecting my routes even when I set id for it?

2

2 Answers

0
votes

Which version of rails are you using? There are examples in rspec-rails github repo on how to do destroy depending on rails version < 5 or rails >5 the syntax is different.

If you rails version is < 5 then try

delete :destroy, {id: user_stock.id}

Another solution would be try to use the delete path so based on your routes something like below

delete "/user_stocks/#{user_stock.id}"

0
votes

Hi I'm working with Rails 5.2.3 and my solution was the following:

delete "/user_stocks/#{user_stock.id}"

However as in some comments on this thread I expirienced a No route matches error, my solution was simple, just save the user_stock object before the delete call. In my case I was testing with an object declared as UserStock.new so it didn't has an id, that's why the delete call was launching an No route matches since it was accessig this path /user_stocks/ instead of user_stocks/:id

Hope this work!