rspec未定义方法`update'为零:NilClass

时间:2017-05-25 16:07:24

标签: ruby-on-rails-4 factory-bot rspec-rails

大家好我有一个问题。我用rspec进行控制器测试,当我测试方法删除和更新时我得到了错误:

 1) TarefasController PATCH #update with valid attributes locates the requested @tarefa
     Failure/Error: if @tarefa.update(tarefa_params)

     NoMethodError:
       undefined method `update' for nil:NilClass
     # ./app/controllers/tarefas_controller.rb:35:in `update'
     # ./spec/controllers/tarefas_controller_spec.rb:82:in `block (4 levels) in <top (required)>'

我不明白错误,为什么会出现这个错误?我的控制器,我的测试和我的FactoryGirls如下:

require 'rails_helper'

RSpec.describe TarefasController, type: :controller do
     login_user

    describe 'GET #index' do
        it "renders the :index template" do
            get :index
            expect(response).to render_template :index
        end
    end


    describe 'GET #show' do
        it "renders the :show template" do
          tarefa = create(:tarefa)
          get :show, id: tarefa
          expect(response).to render_template :show
        end
    end

    describe 'GET #new' do
        it "renders the :new template" do
          get :new
          expect(response).to render_template :new
        end
    end

    describe 'GET #edit' do
        it "renders the :edit template" do
          tarefa = create(:tarefa)
          get :edit, id: tarefa
          expect(response).to render_template :edit
        end
    end

    describe 'POST #create' do
        context "with valid attributes" do
          it "saves the new tarefa in the database" do
            expect{
              post :create, tarefa: attributes_for(:tarefa)
            }.to change(Tarefa, :count).by(1)
          end

          it "redirects to tarefas#show" do
            post :create, tarefa: attributes_for(:tarefa)
            expect(response).to redirect_to Tarefa.first
          end
        end

        context "with invalid attributes" do
          it "does not save the new tarefa in the database" do
            post :create, tarefa: attributes_for(:tarefa, titulo: nil)
            expect(Tarefa.count).to eq(0)
          end

          it "does not save the new tarefa in the database" do
            post :create, tarefa: attributes_for(:tarefa, data: nil)
            expect(Tarefa.count).to eq(0)
          end

          it "re-renders the :new template" do
            post :create, tarefa: attributes_for(:tarefa, data: nil)
            expect(response).to render_template :new
          end

          it "re-renders the :new template" do
            post :create, tarefa: attributes_for(:tarefa, titulo: nil)
            expect(response).to render_template :new
          end
        end
    end

    describe 'PATCH #update' do
        before :each do
            @tarefa = create(:tarefa, titulo: 'Titulo', descricao: 'testando', data: '18/06/2017 20:00', complete: false)
        end

        context "with valid attributes" do
            it "locates the requested @tarefa" do
                patch :update, id: @tarefa.id, tarefa: { titulo: 'Titudlo', descricao: 'testando', data: '18/06/2017 20:00', complete: false}
                expect(assigns(:tarefa)).to eq(@tarefa)
            end
        end
    end
 end

我的控制器:

class TarefasController < ApplicationController

    before_filter :authenticate_user!

    def index
        @tarefas = current_user.tarefas.all.order(:data)
        @data = DateTime.now
    end

    def show
        @tarefa = Tarefa.find(params[:id])
    end

    def new
        @tarefa = Tarefa.new
        @data = DateTime.now.strftime("%Y%m%d%H%M") 
    end

    def edit
        @tarefa = current_user.tarefas.find_by(id: params[:id])
        @data = DateTime.now.strftime("%Y%m%d%H%M") 
    end

    def create
        @tarefa = current_user.tarefas.new(tarefa_params)
        if @tarefa.save
            redirect_to @tarefa
        else
            render 'new'
        end
    end

    def update
        @tarefa = current_user.tarefas.find_by(id: params[:id])
        if @tarefa.update(tarefa_params)
            redirect_to @tarefa
        else
            render 'edit'
        end

    end

    def destroy
        @tarefa = current_user.tarefas.find_by(id: params[:id])
        @tarefa.destroy
        redirect_to tarefas_path
    end

    def complete_index 
        @tarefas = current_user.tarefas.complete.order(:data)
    end

    def complete_update
        @tarefa = current_user.tarefas.find_by(id: params[:id])
        @tarefa.update(complete:true)
        @tarefa.update(data_complete:DateTime.now.strftime("%Y%m%d%H%M") )
    end

    def incomplete_task
        @tarefa = current_user.tarefas.find_by(id: params[:id])
        if @tarefa.update(data_tarefa_params)
            @tarefa.update(complete:false)
            redirect_to complete_index_tarefas_path
        end
    end

    def edit_complete_task
        @tarefa = current_user.tarefas.find_by(id: params[:id])
        @data = DateTime.now.strftime("%Y%m%d%H%M") 
    end

    private
    def tarefa_params
        params.require(:tarefa).permit(:titulo, :descricao, :data, :complete)
    end

    def data_tarefa_params
        params.require(:tarefa).permit(:data)
    end

end

我的规格/工厂/ tarefas.rb:

FactoryGirl.define do
  factory :tarefa do
    association :user
    titulo { Faker::Name.title }
    descricao { Faker::Name.title }
    data {Faker::Time.between(DateTime.now, DateTime.now + 365.days)}
  end
end

我的规范/ factories / users.rb

FactoryGirl.define do
  factory :user do
    email { Faker::Internet.email }
    password { Faker::Internet.password(8) }
  end
end

0 个答案:

没有答案