Search code examples
ruby-on-railsruby-on-rails-4rspecrspec-railsrspec3

RSpec testing destroy controller action throws an error: ActionView::MissingTemplate


I am writing tests for my controller and I get keep getting the error ActionView::MissingTemplate. I have looked at related questions asked before but I can't seem to get it working with my scenario.

Here is my controller code:

def confirm_destroy
  render :layout => 'overlay'
end

def destroy
  @role.destroy
end

And here is the test I have written:

describe 'DELETE #destroy' do
  let!(:role) { create(:role, user: current_user) }
  let(:params) { {id: role.id, format: :json} }

  it 'performs a delete' do
    expect { delete :destroy, params }.to change { Role.count }.by(-1)
  end
end

when I run the test I get the error:

 ActionView::MissingTemplate:
   Missing template company/settings/roles/destroy, application/destroy with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :slim]}. Searched in:
     * "/my_app/app/views"
     * "/usr/local/bundle/gems/devise-4.5.0/app/views"

Any idea why this is so? Thanks.


Solution

  • When controller destroy action is finished, Rails tries to render a default template (view) and it's not defined, meaning you don't have file my_app/app/views/company/settings/roles/destroy.json.

    You have several options to fix it:

    1. Define my_app/app/views/company/settings/roles/destroy.json and it will be rendered (not advised for JSON).
    2. Redirect to other action, e.g. index (again, not advised for JSON).
    3. Render json or explicitly render nothing (see below)

    --

    # render nothing:
    def destroy
      @role.destroy
      head :ok
    end
    
    # render json:
    # render nothing:
    def destroy
      @role.destroy
      render json: { deleted: true }, status: :no_content
    end