7
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Rails】minitestでログインしてる時の処理を書きたい【devise】

Posted at

前提条件

  • Rails5
  • ログイン処理はdeviseを使用
  • minitest

ログインしてる時のtestを書きたい

今、userがpostを複数持っているとします

user.rb
class User < ApplicationRecord
  has_many :posts, dependent: :delete_all
end
post.rb
class Post < ApplicationRecord
  belongs_to :user
end

この時、「新しいpostの新規作成画面」はログインしているユーザーにしか表示したくありません。

posts_controller.rb
class PostsController < ApplicationController
  # ログインしてないユーザーを弾く
  before_action :authenticate_user!, only: [:new]

  def new
    @post = Post.new
  end
end

ここでtestを普通に書くと

posts_controller_test.rb
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するという方法なのですが、これだとエラーが出てうまくいきません。

posts_controller_test.rb
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

ActionDispatch::IntegrationTestに関してはこの書き方でうまく行くはずです

7
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?