如何在 Rails 6 上使用 Minitest 测试 301 重定向

How to test a 301 redirection with Minitest on Rails 6

使用 Rails 6,我从本机 ID (/users/id) 重定向到 friendly_ids (/users/username)(根据 here 带来的答案) 这样处理重定向:

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base

  def redirect_resource_if_not_latest_friendly_id(resource)
    if resource.friendly_id != params[:id]
      redirect_to resource, status: 301
    end
  end
end

在我的控制器中,我这样调用方法:

# app/controllers/users_controller.rb
class UsersController < ApplicationController
  before_action :set_user, only: [:show]

  def show
    redirect_resource_if_not_latest_friendly_id(set_user)
  end

  protected

  def set_user
    @user = User.friendly.find(params[:id])
  end
end

它工作正常,我想在我的测试套件中包含重定向。我找到了关于如何使用 Rspec 做到这一点的答案和主题,但我使用的是 Minitest,但无法弄清楚。

我尝试了很多不同的方法(使用 params[:id] 等),但为了简单起见,我们假设它是以下夹具、测试和结果。

这是固定装置:

# test/fixtures/users.yml
one:
  username: username
  email: email@example.com
  slug: username

这是测试:

# test/controllers/users_controller_test.rb  
class UsersControllerTest < ActionDispatch::IntegrationTest

  test "should 301 redirect to the friendly_id" do
    @user = users(:one)
    get user_path(@user)
    assert_redirected_to "/users/#{@user.slug}"
  end
end

测试结果如下:

FAIL["test_should_301_redirect_to_the_friendly_id", #<Minitest::Reporters::Suite:0x00007fe716c66600 @name="UsersControllerTest">, 0.7785789999979897]
 test_should_301_redirect_to_the_friendly_id#UsersControllerTest (0.78s)
        Expected response to be a <3XX: redirect>, but was a <200: OK>
        test/controllers/users_controller_test.rb:8:in `block in <class:UsersControllerTest>'

我做错了什么?

可能是问题 resource.friendly_id != params[:id] 据我了解它们是相同的

问题是您正在使用“整个”用户记录来发出请求,所以当您这样做时

user_path(@user)

路由从资源中提取 friendly_id,然后你的条件被评估为 false,因为 resource.friendly_id 总是与来自参数的 id 相同。

试试看:

get user_path(id: @user.id)

这样你就可以明确地通过参数传递@user.id。