Search code examples
ruby-on-railsrspecdevisecontrollerdestroy

Rails 4 with Devise, testing Controllers with Rspec


I am new to RSpec testing and currently try to add tests to existing controller for a Rails 4 app. Here is the Github app link, in case you need more details: https://github.com/iacobson/Zero2Dev

resources_controller.rb

    class ResourcesController < ApplicationController
        before_action :authenticate_user!, only:[:new, :create, :destroy]

          def destroy
            @resource = current_user.resources.find(params[:id])
            @resource.destroy
            redirect_to resources_path
          end

        private

        def resource_params
          params.require(:resource).permit(:content, :user_id) 
        end
    end

resources_controller_spec.rb

require 'rails_helper'

RSpec.describe ResourcesController, type: :controller do


  describe "DELETE #destroy" do
    let(:user1) {User.create!(name:"John", email:"john@mail.com", password:"password")}
    let(:user2) {User.create!(name:"Mary", email:"mary@mail.com", password:"password")}
    let(:resource){user1.resources.create!(content: "Neque porro quisquam est qui dolorem ipsum")}


    it "deletes resource when user 1 (that created the resource) is logged-in" do
      sign_in user1
      delete :destroy, id: resource.id
      puts resource.content
      expect(resource.content).to be_nil
    end    
  end        
end

but looks like "resource" never get deleted:

 Failure/Error: expect(resource.content).to be_nil
       expected: nil
            got: "Neque porro quisquam est qui dolorem ipsum"

I tried a lot of other options from Devise tutorial or from other tutorials or answers I found on internet, but all ended in error. I even tried to eliminate the current_user validation from controller, but no chance.

What would be the correct way to test the Destroy action in a controller, using Rails4, Devise and Rspec

Thank you !


Solution

  • The resource you have in your spec is already loaded and doesn't change when the row is deleted from the DB. You can do a couple things:

    Test that the resource is gone from the DB

    expect(Resource.find_by(id: resource.id)).to be_nil
    

    Test that the DB count changes

    expect { delete :destroy, id: resource.id }.to change(Resource, :count).by(-1)