【Rails】minitestでログインしてる時の処理を書きたい【devise】
前提条件
- Rails5
- ログイン処理はdeviseを使用
- minitest
ログインしてる時のtestを書きたい
今、userがpostを複数持っているとします
class User < ApplicationRecord
has_many :posts, dependent: :delete_all
end
class Post < ApplicationRecord
belongs_to :user
end
この時、「新しいpostの新規作成画面」はログインしているユーザーにしか表示したくありません。
class PostsController < ApplicationController
# ログインしてないユーザーを弾く
before_action :authenticate_user!, only: [:new]
def new
@post = Post.new
end
end
ここでtestを普通に書くと
require 'test_helper'
class PostsControllerTest < ActionDispatch::IntegrationTest
def setup
@post = posts(:one)
@user = users(:one)
end
def test_new
get new_post_path
assert_response :success
end
end
$ rails test test/controllers/posts_controller_test.rb
...
Expected response to be a <2XX: success>, but was a <302: Found>
ユーザーがログインしてない状態でアクセスしようとしてるので、当然エラーになってしまうんですね。
deviseでログインしてる前提のテストの書き方を調べました。
Devise::TestHelpersはうまくいかない
調べてみると出てくるのがDevise::TestHelpers
をincludeするという方法なのですが、これだとエラーが出てうまくいきません。
require 'test_helper'
class PostsControllerTest < ActionDispatch::IntegrationTest
include Devise::TestHelpers #追加
def setup
@post = posts(:one)
@user = users(:one)
end
def test_new
sign_in(@user) #追加
get new_post_path
assert_response :success
end
end
テスト実行すると
$ rails test test/controllers/posts_controller_test.rb
E
Error:
PostsControllerTest#test_new:
NoMethodError: undefined method `env' for nil:NilClass
どうやらこれはPostsControllerTestがActiveSupport::TestCase
を継承してる時に使える方法らしいです。
rails g
で生成される標準のtestのファイルの中だと、modelのtestなどはActiveSupport::TestCase
を継承しているのでこの方法が使えます。
ただ、controllerのtestは標準でActionDispatch::IntegrationTest
を継承しているので、この方法だとエラーが出ているんですね。
Warden::Test::Helpersを使おう!
posts_controller_test.rb
require 'test_helper'
class PostsControllerTest < ActionDispatch::IntegrationTest
include Warden::Test::Helpers #追加
def setup
@post = posts(:one)
@user = users(:one)
end
def test_new
login_as(@user, scope: :user) #追加
get new_post_path
assert_response :success
end
end
require 'test_helper'
class PostsControllerTest < ActionDispatch::IntegrationTest
include Warden::Test::Helpers #追加
def setup
@post = posts(:one)
@user = users(:one)
end
def test_new
login_as(@user, scope: :user) #追加
get new_post_path
assert_response :success
end
end
ActionDispatch::IntegrationTest
に関してはこの書き方でうまく行くはずです
Author And Source
この問題について(【Rails】minitestでログインしてる時の処理を書きたい【devise】), 我々は、より多くの情報をここで見つけました https://qiita.com/Kouch/items/13bf961f1d2a24b108ab著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .