为什么这个失败的'undefined方法`破坏'为nil:NilClass'rspec rails

时间:2014-07-15 15:07:08

标签: ruby-on-rails ruby rspec

此测试的想法是处理未找到记录的事件。不应该发生破坏行动,但事实并非如此。我已经切碎并改变了它,坚果基本上测试读起来正确,所以我的代码中一定有问题。

RSpec.describe Admin::EntriesController, :type => :controller do

  setup_factories

  let(:model){ Photo }
  let(:instance){photo}
  let(:no_instances){no_photos}
  let(:some_instances){some_photos}
  let(:params_full_instance){params_full_photo}
  let(:params_new_instance){params_new_photo}

describe "delete destroy" do
      context "where the record is found" do
        before do
          allow(model).to receive(:where).and_return(some_instances)
          allow(some_instances).to receive(:first).and_return(instance)
        end
        context "where the record is destroyed" do
          before do
            allow(instance).to receive(:destroy).and_return(true)
            delete :destroy, params_id
          end
          sets_flash(:notice)
          redirects_to('/admin/entries/rejected')
        end
        context "where the record is not destroyed" do
          before do
            allow(instance).to receive(:destroy).and_return(false)
            delete :destroy, params_id
          end
          sets_flash(:error)
          redirects_to('/admin/entries/rejected')
        end
      end
      context "where the record is not found" do
        before do
          allow(model).to receive(:where).and_return(no_instances)
          delete :destroy, params_id

        end
        sets_flash(:error)
        redirects_to('/admin/entries/rejected')
      end

CONTROLLER

  before_action :get_entry_id, only: [:destroy, :toggle_approve_field, :toggle_reject_field]
    def destroy
       if @entry.nil?
          flash[:error] = "object is not not found"
        end
        if @entry.destroy
          flash[:notice] = 'blah'
          respond_to do |format|
            format.html { redirect_to rejected_admin_entries_path }
            format.json { head :no_content }
            format.js
          end
        else
          flash[:error] = 'There was a problem fetching the record'
          redirect_to rejected_admin_entries_path
        end
      end

    def get_entry_id
        if @entry.nil?
          flash[:error] = "object is not not found"
        end
        @entry = Photo.where(id: params[:id]).first
      end

我可能需要一双新鲜的眼睛。关于我错了什么的一个很好的解释;)

更新:预期的行为是,当进行销毁操作,并且找不到记录时,我希望看到一个闪存错误并被重定向。

更新2:在下面实施了代码,仍然收到错误

 1) Admin::EntriesController for authenticated users delete destroy where the record is not found should set flash error
     Failure/Error: expect(flash[method]).to_not be_nil
       expected: not nil
            got: nil
     # -e:1:in `<main>'

  2) Admin::EntriesController for authenticated users delete destroy where the record is not found should redirect to /admin/entries/rejected
     Failure/Error: expect(response).to redirect_to(path)
       Expected response to be a <redirect>, but was <200>

由于 波多黎各

2 个答案:

答案 0 :(得分:2)

你的问题是你仍在尝试@ entry.destroy,即使它仍然是零。

def destroy
  if @entry.nil?
    flash[:error] = "object is not not found"
  elsif @entry.destroy
    flash[:notice] = 'blah'
    respond_to do |format|
        format.html { redirect_to rejected_admin_entries_path }
        format.json { head :no_content }
        format.js
    end
  else
    flash[:error] = 'There was a problem fetching the record'
    redirect_to rejected_admin_entries_path
  end
end

答案 1 :(得分:2)

问题在于destroy方法。你不是在回电话。这应该有效:

def destroy
   if @entry.nil?
      flash[:error] = "object is not not found"
      return
   end

   if @entry.destroy
      flash[:notice] = 'blah'
      respond_to do |format|
        format.html { redirect_to rejected_admin_entries_path }
        format.json { head :no_content }
        format.js
      end
   else
      flash[:error] = 'There was a problem fetching the record'
      redirect_to rejected_admin_entries_path
   end
  end

无论如何,这段代码是次优的。您应该在before_filter方面找到@entry,如果找不到,则返回404。

如,

before_filter :find_entry

...

def find_entry
  @entry = Entry.find(params[:id])
end