使用者必須登入才能操作 course#new

修改 spec/controllers/courses_controller_spec.rb

describe "GET new" do
  context "when user login" do
    it "assigns @course" do
      user = create(:user)
      course = build(:course)

      sign_in user
      get :new

      expect(assigns(:course)).to be_a_new(Course)
    end

    it "renders template" do
      user = create(:user)
      course = build(:course)

      sign_in user
      get :new

      expect(response).to render_template("new")
    end
  end

  context "when user not login" do
    it "redirect_to new_user_session_path" do
      get :new

      expect(response).to redirect_to new_user_session_path
    end
  end
end

運行 rspec spec/controllers/courses_controller_spec.rb,出現如下訊息:

$ rspec spec/controllers/courses_controller_spec.rb
....FFF..............

Failures:

  1) CoursesController GET new when user login assigns @course
     Failure/Error: user = create(:user)

     ActiveRecord::RecordInvalid:
       Validation failed: Email can't be blank, Password can't be blank
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/configuration.rb:18:in `block in initialize'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/evaluation.rb:15:in `create'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/strategy/create.rb:12:in `block in result'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/strategy/create.rb:9:in `tap'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/strategy/create.rb:9:in `result'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/factory.rb:42:in `run'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/factory_runner.rb:29:in `block in run'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/factory_runner.rb:28:in `run'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/strategy_syntax_method_registrar.rb:20:in `block in define_singular_strategy_method'
     # ./spec/controllers/courses_controller_spec.rb:45:in `block (4 levels) in <top (required)>'

  2) CoursesController GET new when user login renders template
     Failure/Error: user = create(:user)

     ActiveRecord::RecordInvalid:
       Validation failed: Email can't be blank, Password can't be blank
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/configuration.rb:18:in `block in initialize'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/evaluation.rb:15:in `create'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/strategy/create.rb:12:in `block in result'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/strategy/create.rb:9:in `tap'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/strategy/create.rb:9:in `result'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/factory.rb:42:in `run'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/factory_runner.rb:29:in `block in run'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/factory_runner.rb:28:in `run'
     # /Users/Mac/.gem/ruby/2.3.1/gems/factory_girl-4.7.0/lib/factory_girl/strategy_syntax_method_registrar.rb:20:in `block in define_singular_strategy_method'
     # ./spec/controllers/courses_controller_spec.rb:55:in `block (4 levels) in <top (required)>'

  3) CoursesController GET new when user not login redirect_to new_user_session_path
     Failure/Error: expect(response).to redirect_to new_user_session_path
       Expected response to be a <3XX: redirect>, but was a <200: OK>
     # ./spec/controllers/courses_controller_spec.rb:69:in `block (4 levels) in <top (required)>'

Finished in 0.15435 seconds (files took 1.54 seconds to load)
21 examples, 3 failures

抱怨 user 的 email & password 不能為空。

新增 user 的 email & password attributes 在 spec/factories.rb 裡

FactoryGirl.define do
  sequence(:email) { |n| "user#{n}@example.com" }

  factory :user do
    email
    password "password"
    password_confirmation { password }
  end

  factory :course do
    ...
  end
end
$ rspec spec/controllers/courses_controller_spec.rb
....FFF..............

Failures:

  1) CoursesController GET new when user login assigns @course
     Failure/Error: sign_in user

     NoMethodError:
       undefined method `sign_in' for #<RSpec::ExampleGroups::CoursesController::GETNew::WhenUserLogin:0x007fc0944c27d0>
     # ./spec/controllers/courses_controller_spec.rb:48:in `block (4 levels) in <top (required)>'

  2) CoursesController GET new when user login renders template
     Failure/Error: sign_in user

     NoMethodError:
       undefined method `sign_in' for #<RSpec::ExampleGroups::CoursesController::GETNew::WhenUserLogin:0x007fc09432f1c0>
     # ./spec/controllers/courses_controller_spec.rb:58:in `block (4 levels) in <top (required)>'

  3) CoursesController GET new when user not login redirect_to new_user_session_path
     Failure/Error: expect(response).to redirect_to new_user_session_path
       Expected response to be a <3XX: redirect>, but was a <200: OK>
     # ./spec/controllers/courses_controller_spec.rb:69:in `block (4 levels) in <top (required)>'

Finished in 0.17227 seconds (files took 1.57 seconds to load)
21 examples, 3 failures

Failed examples:

rspec ./spec/controllers/courses_controller_spec.rb:44 # CoursesController GET new when user login assigns @course
rspec ./spec/controllers/courses_controller_spec.rb:54 # CoursesController GET new when user login renders template
rspec ./spec/controllers/courses_controller_spec.rb:66 # CoursesController GET new when user not login redirect_to new_user_session_path

沒有 sign_in 方法。

在 Controller spec 中可以透過 devise 登入

devise 提供了 Controller 測試用的 Helper 方法

新增 spec/support/devise.rb

$ touch spec/support/devise.rb

內容

RSpec.configure do |config|
  config.include Devise::Test::ControllerHelpers, type: :controller
end

跑測試:

$ rspec spec/controllers/courses_controller_spec.rb
......F..............

Failures:

  1) CoursesController GET new when user not login redirect_to new_user_session_path
     Failure/Error: expect(response).to redirect_to new_user_session_path
       Expected response to be a <3XX: redirect>, but was a <200: OK>
     # ./spec/controllers/courses_controller_spec.rb:69:in `block (4 levels) in <top (required)>'

Finished in 0.17627 seconds (files took 1.58 seconds to load)
21 examples, 1 failure

Failed examples:

rspec ./spec/controllers/courses_controller_spec.rb:66 # CoursesController GET new when user not login redirect_to new_user_session_path

只剩下一個沒通過的測試,沒登入要跳到登入頁面(new_user_session_path),devise 提供了一個 controller helper: authenticate_user!

class CoursesController < ApplicationController
  before_action :authenticate_user!, only: [:new]

  def index

再執行測試

$ rspec spec/controllers/courses_controller_spec.rb
.....................

Finished in 0.17887 seconds (files took 1.57 seconds to load)
21 examples, 0 failures

通過!現在新增 course 需要登入,沒登入會跳轉到登入頁面。

results matching ""

    No results matching ""