大家好我有一个问题。我用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