RSpec + Capybara:redirect_to 外部页面将我发送回 root_path

Dan*_*G2k 2 rspec ruby-on-rails capybara

我正在尝试编写一个功能测试来检查转到某个路径是否会将用户重定向到外部网站。

为了在我的测试中禁止外部连接,我在我的spec_helper.rb 中有以下内容

require 'webmock/rspec'
WebMock.disable_net_connect!(allow_localhost: true)
Run Code Online (Sandbox Code Playgroud)

我的规范做了类似的事情:

it 'redirects safely' do
  visit "/some/route"

  expect(page).not_to have_content 'MyWebsite'
end
Run Code Online (Sandbox Code Playgroud)

在我的 ApplicationController 中,我有一个before_action应该根据条件从外部重定向:

class ApplicationController < ActionController::Base
  before_action :redirect_to_external_website, if: :unsupported_path

  private

  def redirect_to_external_website
    redirect_to 'https://some.other.website'
  end

  def unsupported_path
    # Some conditions
  end 
end
Run Code Online (Sandbox Code Playgroud)

重定向在开发中按预期工作。

但是,当我运行规范时,我可以看到发生了两次重定向(redirect_to_external_website我认为该方法被命中两次),然后它返回到我的根路径。

知道我可能做错了什么吗?

提前致谢!

Tho*_*ole 5

由于您没有指定与Capybara 一起使用的驱动程序- https://github.com/teamcapybara/capybara#drivers - 我假设您使用的是默认的 rack_test 驱动程序。

rack_test 驱动程序不支持对外部 url 的请求(域信息被忽略,所有路径都直接路由到 AUT)所以你的测试实际上并没有测试你认为它是什么,redirect_to 'https://some.other.website'实际上只是重定向到/你的本地应用程序(因为 rack_test 驱动程序看到 ' https://some.other.website/ ',忽略所有域内容并在您的测试应用程序中将其视为 '/' )。

如果您碰巧使用 Capybara 支持的其他驱动程序之一,该驱动程序支持外部 URL(selenium、poltergeist、capybara-webkit 等),那么您的 WebMock 不会执行您认为的操作,因为它只控制您的 AUT 请求使,它不控制这些驱动程序使用的“浏览器”所做的任何事情,因此它们可以自由地向外部 URL 发出请求。

您尝试测试的功能更适合通过请求规范进行测试 - https://relishapp.com/rspec/rspec-rails/docs/request-specs/request-spec - 而不是通过功能/系统规范进行测试.