如何在 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。
使用 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。