2016-10-26 12 views
-1

Michael Hartl의 Ruby on Rails 튜토리얼에서 장기 휴가 (1 년) 후 연결이 끊어졌습니다. 통합 테스트에서 user_param 오류가 발생했습니다. 필자는 문서를 비롯한 강력한 매개 변수에 대해 잘못 이해할 수있는 원인을 파악하기 위해 4 곳의 출처를 살펴 보았습니다.Ruby on rails 튜토리얼 - 통합 테스트 - 유효/유효하지 않은 사용자 정보 로그인 실패 - user_param 문제?

지난 주에 다시 시작한 이래로 일반적으로 튜토리얼 프로젝트를 알게되어 4 시간이 걸렸으며 7-12 시간에 걸쳐 12 시간을 읽은 다음이 문제를 쫓아 왔습니다. 나는 내가이 물건들에 너무 빨리 스캔해야하는 것처럼 느껴지고있다. & 나는 추적 오류가 좋지 않다는 것을 날카롭게 알고있다.

내가 누락 된 부분에 대해 알려 주실 수 있습니까? 이 유형의 문제를 촬영하는 데 문제가 있으면 알려주고 싶습니다. 시간 내 줘서 고마워! user_signup_test 여기

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

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

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

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

    def new 
    @user = User.new 
    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 
    @user = User.find(params[:id]) 
    end 

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

    private 

    def user_params 
     params.require(:user).permit(:name, :email, :password, 
            :password_confirmation) 
    end 

     # Before filters 

    # 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.admin? 
    end 
end 

것 : 여기

require 'test_helper' 

class UsersSignupTest < ActionDispatch::IntegrationTest 

    def setup 
    ActionMailer::Base.deliveries.clear 
    end 

    test "invalid signup information" do 
    get signup_path 
    assert_no_difference 'User.count' do 
     post users_path, params: { user: { name: "", 
             email: "[email protected]", 
             password:    "foo", 
             password_confirmation: "bar" } } 
    end 
    assert_template 'users/new' 
    assert_select 'div#error_explanation' 
    assert_select 'div.field_with_errors' 
    end 

    test "valid signup information with account activation" do 
    get signup_path 
    assert_difference 'User.count', 1 do 
     post users_path, params: { user: { name: "Example User", 
             email: "[email protected]", 
             password:    "password", 
             password_confirmation: "password" } } 
    end 
    assert_equal 1, ActionMailer::Base.deliveries.size 
    user = assigns(:user) 
    assert_not user.activated? 
     # Try to log in before activation. 
    log_in_as(user) 
    assert_not is_logged_in? 
     # Invalid activation token 
    get edit_account_activation_path("invalid token", email: user.email) 
    assert_not is_logged_in? 
    # Valid token, wrong email 
    get edit_account_activation_path(user.activation_token, email: 'wrong') 
    assert_not is_logged_in? 
     # Valid activation token 
    get edit_account_activation_path(user.activation_token, email: user.email) 
    assert user.reload.activated? 
    follow_redirect! 
    assert_template 'users/show' 
    assert is_logged_in? 
    end 
end 

문제의 컨트롤러 (users_controller) 여기

ERROR["test_password_resets", PasswordResetsTest, 2016-10-20 15:24:37 +0000] 
    test_password_resets#PasswordResetsTest (1476977077.03s) 
    NoMethodError:   NoMethodError: undefined method `[]' for nil:NilClass 
       app/controllers/password_resets_controller.rb:10:in `create' 
       test/integration/password_resets_test.rb:14:in `block in <class:PasswordResetsTest>' 
      app/controllers/password_resets_controller.rb:10:in `create' 
      test/integration/password_resets_test.rb:14:in `block in <class:PasswordResetsTest>' 

    ERROR["test_invalid_signup_information", UsersSignupTest, 2016-10-20 15:24:37 +0000] 
    test_invalid_signup_information#UsersSignupTest (1476977077.04s) 
    ActionController::ParameterMissing:   ActionController::ParameterMissing: param is missing or the value is empty: user 
       app/controllers/users_controller.rb:52:in `user_params' 
       app/controllers/users_controller.rb:25:in `create' 
       test/integration/user_signup_test.rb:12:in `block (2 levels) in <class:UsersSignupTest>' 
       test/integration/user_signup_test.rb:11:in `block in <class:UsersSignupTest>' 
      app/controllers/users_controller.rb:52:in `user_params' 
      app/controllers/users_controller.rb:25:in `create' 
      test/integration/user_signup_test.rb:12:in `block (2 levels) in <class:UsersSignupTest>' 
      test/integration/user_signup_test.rb:11:in `block in <class:UsersSignupTest>' 

    ERROR["test_valid_signup_information_with_account_activation", UsersSignupTest, 2016-10-20 15:24:37 +0000] 
    test_valid_signup_information_with_account_activation#UsersSignupTest (1476977077.05s) 
    ActionController::ParameterMissing:   ActionController::ParameterMissing: param is missing or the value is empty: user 
       app/controllers/users_controller.rb:52:in `user_params' 
       app/controllers/users_controller.rb:25:in `create' 
       test/integration/user_signup_test.rb:25:in `block (2 levels) in <class:UsersSignupTest>' 
       test/integration/user_signup_test.rb:24:in `block in <class:UsersSignupTest>' 
      app/controllers/users_controller.rb:52:in `user_params' 
      app/controllers/users_controller.rb:25:in `create' 
      test/integration/user_signup_test.rb:25:in `block (2 levels) in <class:UsersSignupTest>' 
      test/integration/user_signup_test.rb:24:in `block in <class:UsersSignupTest>' 

    FAIL["test_should_get_edit", PasswordResetsControllerTest, 2016-10-20 15:24:37 +0000] 
    test_should_get_edit#PasswordResetsControllerTest (1476977077.05s) 
      Expected response to be a <success>, but was <302> 
      test/controllers/password_resets_controller_test.rb:11:in `block in <class:PasswordResetsControllerTest>' 

것 : 여기

내가 콘솔에서지고있어 오류 메시지입니다 마지막 컨트롤러입니다 - 그 중 하나를 놓친 ...

require 'test_helper' 

class PasswordResetsTest < ActionDispatch::IntegrationTest 

    def setup 
    ActionMailer::Base.deliveries.clear 
    @user = users(:michael) 
    end 

    test "password resets" do 
    get new_password_reset_path 
    assert_template 'password_resets/new' 
    # Invalid email 
    post password_resets_path, password_reset: { email: "" } 
    assert_not flash.empty? 
    assert_template 'password_resets/new' 
    # Valid email 
    post password_resets_path, 
      password_reset: { email: @user.email } 
    assert_not_equal @user.reset_digest, @user.reload.reset_digest 
    assert_equal 1, ActionMailer::Base.deliveries.size 
    assert_not flash.empty? 
    assert_redirected_to root_url 
    # Password reset form 
    user = assigns(:user) 
    # Wrong email 
    get edit_password_reset_path(user.reset_token, email: "") 
    assert_redirected_to root_url 
    # Inactive user 
    user.toggle!(:activated) 
    get edit_password_reset_path(user.reset_token, email: user.email) 
    assert_redirected_to root_url 
    user.toggle!(:activated) 
    # Right email, wrong token 
    get edit_password_reset_path('wrong token', email: user.email) 
    assert_redirected_to root_url 
    # Right email, right token 
    get edit_password_reset_path(user.reset_token, email: user.email) 
    assert_template 'password_resets/edit' 
    assert_select "input[name=email][type=hidden][value=?]", user.email 
    # Invalid password & confirmation 
    patch password_reset_path(user.reset_token), 
      email: user.email, 
        user: { password:    "foobaz", 
          password_confirmation: "barquux" } 
    assert_select 'div#error_explanation' 
    # Empty password 
    patch password_reset_path(user.reset_token), 
      email: user.email, 
        user: { password:    "", 
          password_confirmation: "" } 
    assert_select 'div#error_explanation' 
    # Valid password & confirmation 
    patch password_reset_path(user.reset_token), 
      email: user.email, 
        user: { password:    "foobaz", 
          password_confirmation: "foobaz" } 
    assert is_logged_in? 
    assert_not flash.empty? 
    assert_redirected_to user 
    end 
end 

PasswordResetController : 나는 당신이 user 매개 변수 전에 params 키를 제거해야한다고 생각

class PasswordResetsController < ApplicationController 
    before_action :get_user,   only: [:edit, :update] 
    before_action :valid_user,  only: [:edit, :update] 
    before_action :check_expiration, only: [:edit, :update] # Case (1) 

    def new 
    end 

    def create 
    @user = User.find_by(email: params[:password_reset][:email].downcase) 
    if @user 
     @user.create_reset_digest 
     @user.send_password_reset_email 
     flash[:info] = "Email sent with password reset instructions" 
     redirect_to root_url 
    else 
     flash.now[:danger] = "Email address not found" 
     render 'new' 
    end 
    end 

    def edit 
    end 

    def update 
    if params[:user][:password].empty?     # Case (3) 
     @user.errors.add(:password, "can't be empty") 
     render 'edit' 
    elsif @user.update_attributes(user_params)   # Case (4) 
     log_in @user 
     flash[:success] = "Password has been reset." 
     redirect_to @user 
    else 
     render 'edit'          # Case (2) 
    end 
    end 

    private 

    def user_params 
     params.require(:user).permit(:password, :password_confirmation) 
    end 

    # Before filters 

    def get_user 
     @user = User.find_by(email: params[:email]) 
    end 

    # Confirms a valid user. 
    def valid_user 
     unless (@user && @user.activated? && 
       @user.authenticated?(:reset, params[:id])) 
     redirect_to root_url 
     end 
    end 

    # Checks expiration of reset token. 
    def check_expiration 
     if @user.password_reset_expired? 
     flash[:danger] = "Password reset has expired." 
     redirect_to new_password_reset_url 
     end 
    end 
end 

답변

1

, 예를 들면 :

또한 당신이 pry와 컨트롤러의 매개 변수를받은 디버깅 할 수 있습니다
test "invalid signup information" do 
    get signup_path 
    assert_no_difference 'User.count' do 
    post users_path, user: { name: "", 
          email: "[email protected]", 
          password: "foo", 
          password_confirmation: "bar" } 
    end 
    assert_template 'users/new' 
    assert_select 'div#error_explanation' 
    assert_select 'div.field_with_errors' 
end 

:

  • gemfile에 pry을 추가하십시오 (아무도없는 경우).
  • run $ bundle install;
  • user_params이 호출되기 전에 컨트롤러에 binding.pry을 추가하십시오.
  • params에 예상 매개 변수가 들어 있는지 확인하십시오.
+0

감사합니다. 양쪽 모두를 위해 그렇게 했어. .. 다른 하나를 찌르는 곳이 확실하지 않다. 그러나 굉장한 & 빠른 응답! 여전히 "test_password_resets", PasswordResetsTest 및 "test_should_get_edit", PasswordResetsControllerTest – Mirv

+0

PS : 11 월 20 일자로 Michael Hartl 's 가이드를 사용하는 다른 사용자의 경우 params &에 대한 마지막 개정 이후 허용 된 구문이 변경되었습니다. rake/rails 명령이 콘솔에 자주 나열되지 않습니다. – Mirv