質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.36%

  • Ruby

    8760questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    8164questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

【RailsTutorial】テスト時のエラーの原因がわからない【11章 11.3.3 】

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 187

y_y.

score 8

 前提・実現したいこと

現在、Ruby on Rails Tutorial を写経しながら学習を進めています。
標題の節を進めているのですが、途中のテストでredになってしまいます。
原因がわかる方がいらっしゃいましたらご教示願います。

 発生している問題・エラーメッセージ

$ rails t

Running via Spring preloader in process 6077
Started with run options --seed 22425

ERROR["test_login_with_remembering", UsersLoginTest, 1.4186359340001218]
 test_login_with_remembering#UsersLoginTest (1.42s)
NoMethodError:         NoMethodError: undefined method `remember_token' for nil:NilClass
            test/integration/users_login_test.rb:43:in `block in <class:UsersLoginTest>'

  42/42: [=============================================================================================================] 100% Time: 00:00:01, Time: 00:00:01

Finished in 1.50971s
42 tests, 176 assertions, 0 failures, 1 errors, 0 skips

NoMethodError: undefined method 'remember_token' for nil:NilClassとあります。
第9章の演習 (9.3.1.1)でapp/controllers/sessions_controller.rb内の通常のローカル変数userをインスタンス変数@userに変更していましたが、11章のリスト (11.32)で再びuserに戻したことがこのエラーの原因かと思われます。

統合テストでは、仮想の`remember_token`属性にアクセスできない
↓
`assigns`という特殊なテストメソッドを使うとアクセスできるようになる
↓
`@user`というインスタンス変数が定義されていれば、テスト内部では`assigns(:user)`と書くことでインスタンス変数にアクセスできる。

という経緯で9章で変更していました。

なので、再び@userに変更し、テストを行ったところ…

Running via Spring preloader in process 6799
Started with run options --seed 48516

ERROR["test_login_with_remembering", UsersLoginTest, 0.7189132280000194]
 test_login_with_remembering#UsersLoginTest (0.72s)
NameError:         NameError: undefined local variable or method `user' for #<SessionsController:0x00000007645378>
        Did you mean?  @user
            app/controllers/sessions_controller.rb:9:in `create'
            test/test_helper.rb:29:in `log_in_as'
            test/integration/users_login_test.rb:42:in `block in <class:UsersLoginTest>'

ERROR["test_login_with_valid_information_followed_by_logout", UsersLoginTest, 0.7384869200004687]
 test_login_with_valid_information_followed_by_logout#UsersLoginTest (0.74s)
NameError:         NameError: undefined local variable or method `user' for #<SessionsController:0x007fde602f1598>
        Did you mean?  @user
            app/controllers/sessions_controller.rb:9:in `create'
            test/integration/users_login_test.rb:21:in `block in <class:UsersLoginTest>'

ERROR["test_login_without_remembering", UsersLoginTest, 0.7538774949998697]
 test_login_without_remembering#UsersLoginTest (0.75s)
NameError:         NameError: undefined local variable or method `user' for #<SessionsController:0x000000078ad570>
        Did you mean?  @user
            app/controllers/sessions_controller.rb:9:in `create'
            test/test_helper.rb:29:in `log_in_as'
            test/integration/users_login_test.rb:48:in `block in <class:UsersLoginTest>'

ERROR["test_successful_edit", UsersEditTest, 0.7702211570003783]
 test_successful_edit#UsersEditTest (0.77s)
NameError:         NameError: undefined local variable or method `user' for #<SessionsController:0x00000004319a30>
        Did you mean?  @user
            app/controllers/sessions_controller.rb:9:in `create'
            test/test_helper.rb:29:in `log_in_as'
            test/integration/users_edit_test.rb:22:in `block in <class:UsersEditTest>'

ERROR["test_successful_edit_with_friendly_forwarding", UsersEditTest, 0.8101292460005425]
 test_successful_edit_with_friendly_forwarding#UsersEditTest (0.81s)
NameError:         NameError: undefined local variable or method `user' for #<SessionsController:0x000000078a9d80>
        Did you mean?  @user
            app/controllers/sessions_controller.rb:9:in `create'
            test/test_helper.rb:29:in `log_in_as'
            test/integration/users_edit_test.rb:41:in `block in <class:UsersEditTest>'

ERROR["test_unsuccessful_edit", UsersEditTest, 0.8249431140002343]
 test_unsuccessful_edit#UsersEditTest (0.83s)
NameError:         NameError: undefined local variable or method `user' for #<SessionsController:0x000000076293d0>
        Did you mean?  @user
            app/controllers/sessions_controller.rb:9:in `create'
            test/test_helper.rb:29:in `log_in_as'
            test/integration/users_edit_test.rb:10:in `block in <class:UsersEditTest>'

ERROR["test_valid_signup_information_with_account_activation", UsersSignupTest, 1.1824065370001335]
 test_valid_signup_information_with_account_activation#UsersSignupTest (1.18s)
NameError:         NameError: undefined local variable or method `user' for #<SessionsController:0x0000000951a5f0>
        Did you mean?  @user
            app/controllers/sessions_controller.rb:9:in `create'
            test/test_helper.rb:29:in `log_in_as'
            test/integration/users_signup_test.rb:34:in `block in <class:UsersSignupTest>'

ERROR["test_should_redirect_update_when_logged_in_as_wrong_user", UsersControllerTest, 1.2318844230003378]
 test_should_redirect_update_when_logged_in_as_wrong_user#UsersControllerTest (1.23s)
NameError:         NameError: undefined local variable or method `user' for #<SessionsController:0x0000000969f358>
        Did you mean?  @user
            app/controllers/sessions_controller.rb:9:in `create'
            test/test_helper.rb:29:in `log_in_as'
            test/controllers/users_controller_test.rb:41:in `block in <class:UsersControllerTest>'

ERROR["test_should_redirect_destroy_when_logged_in_as_a_non-admin", UsersControllerTest, 1.2460524620000797]
 test_should_redirect_destroy_when_logged_in_as_a_non-admin#UsersControllerTest (1.25s)
NameError:         NameError: undefined local variable or method `user' for #<SessionsController:0x00000009797990>
        Did you mean?  @user
            app/controllers/sessions_controller.rb:9:in `create'
            test/test_helper.rb:29:in `log_in_as'
            test/controllers/users_controller_test.rb:66:in `block in <class:UsersControllerTest>'

ERROR["test_should_not_allow_the_admin_attribute_to_be_edited_via_the_web", UsersControllerTest, 1.2702050879997842]
 test_should_not_allow_the_admin_attribute_to_be_edited_via_the_web#UsersControllerTest (1.27s)
NameError:         NameError: undefined local variable or method `user' for #<SessionsController:0x000000098d47e0>
        Did you mean?  @user
            app/controllers/sessions_controller.rb:9:in `create'
            test/test_helper.rb:29:in `log_in_as'
            test/controllers/users_controller_test.rb:49:in `block in <class:UsersControllerTest>'

ERROR["test_should_redirect_edit_when_logged_in_as_wrong_user", UsersControllerTest, 1.2845417730004556]
 test_should_redirect_edit_when_logged_in_as_wrong_user#UsersControllerTest (1.28s)
NameError:         NameError: undefined local variable or method `user' for #<SessionsController:0x000000099c9010>
        Did you mean?  @user
            app/controllers/sessions_controller.rb:9:in `create'
            test/test_helper.rb:29:in `log_in_as'
            test/controllers/users_controller_test.rb:34:in `block in <class:UsersControllerTest>'

ERROR["test_index_as_admin_including_pagination_and_delete_links", UsersIndexTest, 1.3651507889999266]
 test_index_as_admin_including_pagination_and_delete_links#UsersIndexTest (1.37s)
NameError:         NameError: undefined local variable or method `user' for #<SessionsController:0x00000009cf3bf0>
        Did you mean?  @user
            app/controllers/sessions_controller.rb:9:in `create'
            test/test_helper.rb:29:in `log_in_as'
            test/integration/users_index_test.rb:11:in `block in <class:UsersIndexTest>'

ERROR["test_index_as_non-admin", UsersIndexTest, 1.3875819069999125]
 test_index_as_non-admin#UsersIndexTest (1.39s)
NameError:         NameError: undefined local variable or method `user' for #<SessionsController:0x00000009cf7a48>
        Did you mean?  @user
            app/controllers/sessions_controller.rb:9:in `create'
            test/test_helper.rb:29:in `log_in_as'
            test/integration/users_index_test.rb:28:in `block in <class:UsersIndexTest>'

  42/42: [=============================================================================================================] 100% Time: 00:00:01, Time: 00:00:01

Finished in 1.39742s
42 tests, 70 assertions, 0 failures, 13 errors, 0 skips

エラーが増えてしまいました。

 試したこと

user を @user に変更するということだと思うのですが、どれを変更して良いのかがよく理解できていません。

補足情報(FW/ツールのバージョンなど)

AWS Cloud9
Rails 5.1.6

以上になります。
お分かりになる方がいらっしゃいましたら、何卒、宜しくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

 該当のソースコード

sessions_controller.rb

 class SessionsController < ApplicationController

  def new
  end

  def create
    @user = User.find_by(email: params[:session][:email].downcase)
    if @user && @user.authenticate(params[:session][:password])
      if user.activated?
        log_in @user
        params[:session][:remember_me] == '1' ? remember(@user) : forget(@user)
        redirect_back_or @user
      else
        message  = "Account not activated. "
        message += "Check your email for the activation link."
        flash[:warning] = message
        redirect_to root_url
      end
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end

  def destroy
    log_out if logged_in?
    redirect_to root_url
  end
end


test_helper.rb

 ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require "minitest/reporters"
Minitest::Reporters.use!

class ActiveSupport::TestCase
  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all
  include ApplicationHelper

  # Add more helper methods to be used by all tests here...

  # テストユーザーがログイン中の場合にtrueを返す
  def is_logged_in?
    !session[:user_id].nil?
  end

  # テストユーザーとしてログインする
  def log_in_as(user)
    session[:user_id] = user.id
  end
end

class ActionDispatch::IntegrationTest

  # テストユーザーとしてログインする
  def log_in_as(user, password: 'password', remember_me: '1')
    post login_path, params: { session: { email: user.email,
                                          password: password,
                                          remember_me: remember_me } }
  end
end


users_login_test.rb

 require 'test_helper'

class UsersLoginTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:michael)
  end

  test "login with invalid information" do
    get login_path
    assert_template 'sessions/new'
    post login_path, params: { session: { email: "", password: "" } }
    assert_template 'sessions/new'
    assert_not flash.empty?
    get root_path
    assert flash.empty?
  end

  test "login with valid information followed by logout" do
    get login_path
    post login_path, params: { session: { email:    @user.email,
                                          password: 'password' } }
    assert is_logged_in?
    assert_redirected_to @user
    follow_redirect!
    assert_template 'users/show'
    assert_select "a[href=?]", login_path, count: 0
    assert_select "a[href=?]", logout_path
    assert_select "a[href=?]", user_path(@user)
    delete logout_path
    assert_not is_logged_in?
    assert_redirected_to root_url
    # 2番目のウィンドウでログアウトをクリックするユーザーをシミュレートする
    delete logout_path
    follow_redirect!
    assert_select "a[href=?]", login_path
    assert_select "a[href=?]", logout_path,      count: 0
    assert_select "a[href=?]", user_path(@user), count: 0
  end

  test "login with remembering" do
    log_in_as(@user, remember_me: "1")
    assert_equal cookies['remember_token'], assigns(:user).remember_token
  end

  test "login without remembering" do
    # クッキーを保存してログイン
    log_in_as(@user, remember_me: '1')
    delete logout_path
    # クッキーを削除してログイン
    log_in_as(@user, remember_me: '0')
    assert_empty cookies['remember_token']
  end

end


users_controller_test.rb

require 'test_helper'

class UsersControllerTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:michael)
    @other_user = users(:archer)
  end

   test "should redirect index when not logged in" do
    get users_path
    assert_redirected_to login_url
  end

  test "should get new" do
    get signup_path
    assert_response :success
  end

  test "should redirect edit when not logged in" do
    get edit_user_path(@user)
    assert_not flash.empty?
    assert_redirected_to login_url
  end

  test "should redirect update when not logged in" do
    patch user_path(@user), params: { user: { name: @user.name,
                                              email: @user.email } }
    assert_not flash.empty?
    assert_redirected_to login_url
  end

  test "should redirect edit when logged in as wrong user" do
    log_in_as(@other_user)
    get edit_user_path(@user)
    assert flash.empty?
    assert_redirected_to root_url
  end

  test "should redirect update when logged in as wrong user" do
    log_in_as(@other_user)
    patch user_path(@user), params: { user: { name: @user.name,
                                              email: @user.email } }
    assert flash.empty?
    assert_redirected_to root_url
  end

  test "should not allow the admin attribute to be edited via the web" do
    log_in_as(@other_user)
    assert_not @other_user.admin?
    patch user_path(@other_user), params: {
                                    user: { password:              @other_user.password,
                                            password_confirmation: @other_user.password_confirmation,
                                            admin: true } }
    assert_not @other_user.reload.admin?
  end

  test "should redirect destroy when not logged in" do
    assert_no_difference 'User.count' do
      delete user_path(@user)
    end
    assert_redirected_to login_url
  end

  test "should redirect destroy when logged in as a non-admin" do
    log_in_as(@other_user)
    assert_no_difference 'User.count' do
      delete user_path(@user)
    end
    assert_redirected_to root_url
  end

end


users_index_test.rb

 require 'test_helper'

class UsersIndexTest < ActionDispatch::IntegrationTest

  def setup
    @admin     = users(:michael)
    @non_admin = users(:archer)
  end

  test "index as admin including pagination and delete links" do
    log_in_as(@admin)
    get users_path
    assert_template 'users/index'
    assert_select 'div.pagination'
    first_page_of_users = User.paginate(page: 1)
    first_page_of_users.each do |user|
      assert_select 'a[href=?]', user_path(user), text: user.name
      unless user == @admin
        assert_select 'a[href=?]', user_path(user), text: 'delete'
      end
    end
    assert_difference 'User.count', -1 do
      delete user_path(@non_admin)
    end
  end

  test "index as non-admin" do
    log_in_as(@non_admin)
    get users_path
    assert_select 'a', text: 'delete', count: 0
  end

end

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Ruby

    8760questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails

    8164questions

    Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。