ぞえの技術めも

Ruby on Rails勉強中

【91日目】【1日20分のRailsチュートリアル】【第8章】“Remember me”チェックボックスをテストする

Ruby on Railsチュートリアル(第3版)

今日は「8.4.6 Rememberのテスト」から。

8.4.6 Rememberのテスト

しかしもっと重要な理由は、ユーザーを永続化するコードの中心部分が、実はまだまったくテストされていないからです。

そうだっけ…そうかもしれない。。。
ユーザーの永続化によって見た目がどう変わるか、リンクテキストはどうなるか、のテストだったような気もする。

[remember me] ボックスをテストする

リスト8.20では、postメソッドと有効なsessionハッシュを使用してログインしましたが、毎回このようなことをするのは面倒です。
そこで、log_in_asというヘルパーメソッドを作成してテスト用にログインできるようにし、無駄な繰り返しを排除します。

うぅーん、、なんだかログイン処理のテストって難しいね。。。解説を理解するのに時間かかる…。

統合テストの内部では、リスト8.20のようにセッションパスをpostしますが、コントローラやモデルなどの単体テストでは同じ方法が使えません (セッションがないからです)。

分かるような分からないような感じだけど統合テストと単体テストでコードを分ける必要があるんですね。

test/test_helper.rb

  # テストユーザーとしてログインする
  def log_in_as(user, options = {})
    password    = options[:password]    || 'password'
    remember_me = options[:remember_me] || '1'
    if integration_test?
      post login_path, session: { email:       user.email,
                                  password:    password,
                                  remember_me: remember_me }
    else
      session[:user_id] = user.id
    end
  end

  private

    # 統合テスト内ではtrueを返す
    def integration_test?
      defined?(post_via_redirect)
    end

まずdefined?(post_via_redirect)で統合テストかどうかが分かるのでメソッド化して、 統合テストであればPOSTメソッドでログイン処理して、 統合テストじゃなければセッションを作成するような感じか。。。

cookiesの値がユーザーの記憶トークンと一致することを確認できれば理想的なのですが、現在の設計ではテストでこの確認を行うことはできません。

テスト用の@userインスタンスにはremember_tokenが含まれていないそう。
この辺よく分からないけど、、、まぁいいか。

さしあたって、今は関連するcookiesがnilであるかどうかだけをチェックすればよいことにします。

チェックボックスがオンであればcookiesがnilじゃないこと、
チェックボックスがオフであればcookiesがnilなことを確認する。

test/integration/users_login_test.rb

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

  test "login without remembering" do
    log_in_as(@user, remember_me: '0')
    assert_nil cookies['remember_token']
  end

テスト実行して問題ないことを確認。

$ bundle exec rake test
27 tests, 64 assertions, 0 failures, 0 errors, 0 skips

ユーザー関連のテスト難しいわ。。。

今日の作業時間は【35分】

次は「8.4.6 Rememberのテスト」の「記憶ブランチをテストする」から。