Rspec错误:ParameterMissing:缺少param或值为空:user

时间:2015-10-09 23:05:53

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-4 rspec

我正在使用Rspec测试用户控制器的Update操作。

我收到此错误:

UsersController POST #update user updated
     Failure/Error: patch :update, {id: user.id }, { user_id: user.id }, user: user_params
     ActionController::ParameterMissing:
       param is missing or the value is empty: user
     # /Users/joseph/.rvm/gems/ruby-2.1.2/gems/actionpack-4.2.0/lib/action_controller/metal/strong_parameters.rb:249:in `require'
     # ./app/controllers/users_controller.rb:60:in `user_params'
     # ./app/controllers/users_controller.rb:39:in `update'

奇怪的是我使用binding.pry来测试正在发生的事情。 有一个用户,还有user_params。所以我不明白为什么会收到上述错误。

请参阅下面的用户和用户参数。

From: /Users/joseph/Documents/Safsy/Website/Safsy/Safsy/spec/controllers/users_controller_spec.rb @ line 76 :

    71:     end
    72:   end
    73:
    74:   describe "POST #update" do
    75:     it "user updated" do
 => 76:       binding.pry
    77:       patch :update, {id: user.id }, { user_id: user.id }, user: user_params
    78:       expect(response).to redirect_to(assigns(:user))
    79:       expect(assigns(:user)).to eq(user)
    80:     end
    81:   end

[1] pry(#<RSpec::ExampleGroups::UsersController::POSTUpdate>)> patch :update, {id: user.id }, { user_id: user.id }, user: user_params
ActionController::ParameterMissing: param is missing or the value is empty: user
from /Users/joseph/.rvm/gems/ruby-2.1.2/gems/actionpack-4.2.0/lib/action_controller/metal/strong_parameters.rb:249:in `require'
[2] pry(#<RSpec::ExampleGroups::UsersController::POSTUpdate>)> user
=> #<User:0x007fd91fe40458
 id: 2,
 username: "username2",
 email: "user2@factory.com",
 created_at: Thu, 08 Oct 2015 11:09:54 UTC +00:00,
 updated_at: Thu, 08 Oct 2015 11:09:54 UTC +00:00,
 password_digest: "$2a$04$YsvGZ05kdqMoa5fhJlkh1Oa9ISN6wuO7TBCT23vVDS.UO1k.vKTA2",
 remember_digest: nil,
 admin: false,
 activation_digest: "$2a$04$GzFp9Otdlo7l1JBPOTeiQu7NUZELLQSIkLZUd7df1h2p4XpqNXLMm",
 activated: true,
 activated_at: nil,
 reset_digest: nil,
 >: nil,
 reset_sent_at: nil,
 avatar_file_name: nil,
 avatar_content_type: nil,
 avatar_file_size: nil,
 avatar_updated_at: nil,
 description: "Corporis odio magni repellendus.",
 header_image_file_name: nil,
 header_image_content_type: nil,
 header_image_file_size: nil,
 header_image_updated_at: nil>
[3] pry(#<RSpec::ExampleGroups::UsersController::POSTUpdate>)> user_params
=> {:username=>"username512",
 :email=>"user463@factory.com",
 :password=>"Password123",
 :password_confirmation=>"Password123",
 :admin=>false,
 :description=>"Nihil eligendi ab debitis iure."}
[4] pry(#<RSpec::ExampleGroups::UsersController::POSTUpdate>)>

这是完整的测试。失败的测试是更新操作。它是对此文件的最后一次测试。

require "rails_helper"

RSpec.describe UsersController, type: :controller do
  let!(:admin) { create(:user, password: "Password123", admin: true) }
  let!(:user) { create(:user, password: "Password456", admin: false) }

  let!(:users) do
    [admin, user] + 3.times.map { create(:user) }
  end

  let!(:user_params) { user_params = { username: "username#{rand(1000)}",
                                       email: "user#{rand(1000)}@factory.com",
                                       password: "Password123",
                                       password_confirmation: "Password123",
                                       admin: false,
                                       description: "Nihil eligendi ab debitis iure.",
                                      } }

  let!(:category) { create(:category, name: "Shirt") }
  let!(:category1) { create(:category, name: "Short") }

  describe "GET #index" do
    it "admin user renders template and shows users" do
      get :index, {}, { user_id: admin.id }
      expect(response).to render_template(:index)
      expect(response).to have_http_status(:success)
      expect(assigns(:users).map(&:id)).to eq users.map(&:id)
    end

    it "user renders template and shows users" do
      get :index, {}, { user_id: user.id }
      expect(response).to redirect_to(root_path)
    end

    it "redirects visitor" do
      get :index
      expect(response).to redirect_to(root_path)
    end
  end

  describe "GET #show" do
    it "user renders template and shows user" do
      get :show, id: user.id
      expect(response).to render_template(:show)
      expect(response).to have_http_status(:success)
      expect(assigns(:user)).to eq(user)
    end
  end

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

  describe "POST #create" do
    it "user created" do
      post :create, user: user_params
      expect(assigns(:user)).to be_persisted
    end
  end

  describe "GET #edit" do
    it "user edit" do
      get :edit, {id: user.id }, { user_id: user.id }
      expect(response).to render_template(:edit)
      expect(response).to have_http_status(:success)
      expect(assigns(:user)).to eq(user)
    end
  end

  describe "POST #update" do
    it "user updated" do
      patch :update, {id: user.id }, { user_id: user.id }, user: user_params
      expect(response).to redirect_to(assigns(:user))
      expect(assigns(:user)).to eq(user)
    end
  end

用户控制器

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :update, :edit]
  before_action :logged_in_user, only: [:edit, :update, :destroy]
  before_action :correct_user,   only: [:edit, :update]
  before_action :admin_user,     only: [:destroy, :index]

  def index
    @users = User.paginate(page: params[:page])
  end

  def new
    @user = User.new
  end

  def show
    @items = @user.items.paginate(page: params[:page])
  end

  def show_user_items
    @user = User.find(current_user)
    @items = @user.items.paginate(page: params[:page])
  end

  def create
    @user = User.new(user_params)
    if @user.save
      @user.send_activation_email
      flash[:info] = "Please check your email to activate your account."
      redirect_to root_url
    else
      render 'new'
    end
  end

  def edit
  end

  def update
    if @user.update_attributes(user_params)
      flash[:success] = "Profile updated"
      redirect_to @user
    else
      render 'edit'
    end
  end

  def destroy
    User.find(params[:id]).destroy
    flash[:success] = "User deleted"
    redirect_to users_path
  end

  private

  def set_user
    @user = User.find(params[:id])
  end

  def user_params
    params.require(:user).permit(
      :username,
      :email,
      :password,
      :password_confirmation,
      :avatar,
      :header_image,
      :description
    )
  end

  # Confirms a logged-in user.
  def logged_in_user
    unless logged_in?
      store_location
      flash[:danger] = "Please log in."
      redirect_to login_url
    end
  end

  # Confirms the correct user.
  def correct_user
    @user = User.find(params[:id])
    redirect_to(root_url) unless current_user?(@user)
  end

  # Confirms an admin user.
  def admin_user
    redirect_to(root_url) unless current_user.try(:admin?)
  end
end

这是我的log_in方法

      def log_in(user)
        session[:user_id] = user.id
      end

  def logged_in?
    !current_user.nil?
  end

  def current_user
    if (user_id = session[:user_id])
      @current_user ||= User.find_by(id: user_id)
    elsif (user_id = cookies.signed[:user_id])
      user = User.find_by(id: user_id)
      if user && user.authenticated?(:remember, cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end

1 个答案:

答案 0 :(得分:0)

在您的测试中,您在参数中没有user,所以它没有收到此错误消息:

param is missing or the value is empty: user

您应该在user中发送params,如下所示:

  let!(:user) { create(:user, password: "Password456", admin: false) }
  let!(:update_params) do
    { id: user.id, user_id: user.id, user: user }
  end

  patch :update, update_params

这可以解决您的问题。