无法测试 POST 中设置的会话 [:user_id] 值 #create in SessionsController spec with RSpec/Rails

Unable to test the session[:user_id] value set in POST #create in SessionsController spec with RSpec/Rails

我正在为如何正确测试 SessionsController 中的 POST #create 操作而苦恼。我试图存根身份验证。我的假设是,在执行 post :create 操作之后,有效测试应该测试 session[:user_id] 实际上等于 @user.id 值。但是,我得到 nil 返回 session[:user_id].

模拟、存根等对我来说还是有点新鲜。用于身份验证的存根看起来非常简单。但是,为什么我运行这个测试的时候获取不到返回的session值?

有效身份验证测试当前失败(尽管它在实际操作中有效——即我可以登录该应用程序)。这是我关心的。第二个测试(无效密码)通过了,看起来很好。我的所有其他会话控制器规格都通过了。

这是我的 sessions_controller_spec.rb 文件中通过 POST #create:

处理会话创建的部分
require 'rails_helper'

describe SessionsController, type: :controller do
 describe "POST #create" do
  context "where authentication is valid" do
   it "creates a new session with a welcome message" do
    @user = create(User, id: 1)
    allow(@user).to receive(:authenticate).and_return @user

    post :create, email: "test@example.com", password: "secret1234"

    expect(session[:user_id]).to eq @user.id
    expect(flash[:notice]).to match("Welcome back!")
  end
 end

 context "where password is invalid" do
  it "re-renders the signin page with an alert message" do
    user = create(:user)

    post :create, session: { email: user.email, password: 'invalid' }

    expect(response).to render_template :new
    expect(flash[:alert]).to match("Incorrect email/password combination!")
   end
  end
 end

 # CODE FOR OTHER TESTS OMITTED

end

这是我的 sessions_controller.rb 文件:

class SessionsController < ApplicationController

  def new
  end

  def create
    if user = User.authenticate(params[:email], params[:password])
      session[:user_id] = user.id
      flash[:notice] = "Welcome back!"
      redirect_to root_path
    else
      flash.now[:alert] = "Incorrect email/password combination!"
      render :new
    end
  end

  def destroy
    session[:user_id] = nil
    redirect_to new_session_path, notice: "Signed Out!"
  end
end

测试returns出现如下错误:

 1) SessionsController POST #create where authentication is valid creates a new session with a welcome message
     Failure/Error: expect(session[:user_id]).to eq @user.id

       expected: 1
            got: nil

       (compared using ==)
     # ./spec/controllers/sessions_controller_spec.rb:12:in `block (4 levels) in <top (required)>'
     # ./spec/rails_helper.rb:42:in `block (3 levels) in <top (required)>'
     # ./spec/rails_helper.rb:41:in `block (2 levels) in <top (required)>'

是否有更好的或首选的方法来测试 SessionsController 是否成功创建会话并设置会话[:user_id]值?

欢迎评论、代码评论等。

你没有正确地存根方法:

allow(@user).to receive(:authenticate).and_return @user

在控制器中,您在 class 上调用 authenticate,而不是实例。上面一行应该是:

allow(User).to receive(:authenticate).and_return @user