首页 > 解决方案 > 如何使用 Minitest on Rails 6 测试 301 重定向

问题描述

使用 Rails 6,我从本机 ids ( /users/id) 重定向到 friendly_ids ( )(按照这里/users/username带来的答案),它处理重定向如下:

# 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>'

我究竟做错了什么?

标签: ruby-on-railsredirectminitest

解决方案


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

user_path(@user)

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

请尝试:

get user_path(id: @user.id)

这样您就可以通过参数显式传递@user.id。


推荐阅读