预期响应的状态代码为 200,但在 rspec 中的请求测试中为 302

Expected the response to have status code 200 but it was 302 in requests test in rspec

我发现其他人发布了很多类似的问题,但 none 的解决方案有效。

我的 /spec/requests/questions_spec.rb 是

require 'rails_helper'
RSpec.describe "Questions", type: :request do
  describe "GET /questions" do
    it "works! (now write some real specs)" do
      get questions_path
      expect(response).to have_http_status(200)
    end
  end
end

现在我的rspec错误

Questions GET /questions works! (now write some real specs)
 Failure/Error: expect(response).to have_http_status(200)
   expected the response to have status code 200 but it was 302
 # ./spec/requests/questions_spec.rb:7:in `block (3 levels) in <top (required)>'

谁能帮帮我?如何自定义我的代码以获得状态代码 200?

302 - Found。我认为您正在使用 rails 脚手架。脚手架语法 return get 方法的 302 状态。如果你需要200。你可以自定义你的代码。

我认为您缺少身份验证。

使用login_user

https://github.com/heartcombo/devise/wiki/How-To:-Test-controllers-with-Rails-(and-RSpec)

我遇到了类似的问题 expected the response to have a success status code (2xx) but it was 302 当我正确处理这段代码时

描述"GET #index"做

  it "returns http success" do
    get :index
    expect(response).to have_http_status(:success)
  end
end

你知道吗:我没有使用 devise gem 所以我不能使用 login_user 不幸的是我忘记了如何在没有 devise 的情况下实现登录。它以某种方式使用 session 保持登录状态。所以我做了这样的事情并且成功了:

描述"GET #index"做

  it "returns http success" do

      admin = User.create(name:  "admin@gmail.com",
           email: "admin@gmail.com",
           password:              "admin@gmail.com",
           password_confirmation: "admin@gmail.com",
           admin:     true,
           activated: true,
           activated_at: Time.zone.now)

      session[:user_id] = admin.id

    get :index
    expect(response).to have_http_status(:success)
  end

end

您很可能正在使用@Velusamy Venkatraman 和@Raj 提到的脚手架生成方法。所以,如果你想获得 2xx 状态,你需要sign_in,这意味着完全成功。 302 状态表示页面存在但您被重定向(主要是在出现错误的情况下)。

执行以下操作来解决问题:

第 1 步: 您可以在 spec 文件夹中创建如下自定义方法,然后简单地使用它们:

module ControllerMacros
  def login_admin
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:admin]
      sign_in FactoryBot.create(:user, admin:true)
    end
  end

  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      sign_in FactoryBot.create(:user)
    end
  end
end

第 2 步:

login_userlogin_admin 添加到您需要的规范文件中并更改

let(:valid_session) { {} }

let(:valid_session) { {"warden.user.user.key" => session["warden.user.user.key"]} }

我希望你正在使用 devisewarden 如果你不想担心 session/login/signup 问题,它们真的很有用。

您可以在此处查看他们的文档: plataformatec/devise wardencommunity/warden

此答案是根据设计文档编写的: devise-wiki-how-to-test