【问题标题】:How do I set HTTP_REFERER when testing in Rails?在 Rails 中测试时如何设置 HTTP_REFERER?
【发布时间】:2009-02-12 19:25:05
【问题描述】:

我正在尝试测试控制器并收到此错误。我了解错误,但不知道如何解决。

test: on CREATE to :user with completely invalid email should respond with 
  redirect
(UsersControllerTest):ActionController::RedirectBackError: 
  No HTTP_REFERER was set in the request to this action, 
  so redirect_to :back could not be called successfully. 
If this is a test, make sure to specify request.env["HTTP_REFERER"].

在哪里指定?我试过这个:

setup { post :create, { :user => { :email => 'invalid@abc' } }, 
  { 'referer' => '/sessions/new' } }

但是遇到了同样的错误。

具体用什么来指定?我想我希望它返回到的视图的 URI:

'/sessions/new'

这就是他们的意思吗?


好的,事实证明他们的意思是这样做:

setup do
  @request.env['HTTP_REFERER'] = 'http://localhost:3000/sessions/new'
  post :create, { :user => { :email => 'invalid@abc' } }, {}
end

谁能告诉我记录在哪里?我想了解一下这些信息的背景。

如果域不是“localhost:3000”怎么办?如果它是“localhost:3001”或其他什么?有什么方法可以预测吗?

为什么这不起作用:

setup { post :create, { :user => { :email => 'invalid@abc' } }, 
  { 'referer' => '/sessions/new' } }

Rails 文档 specifically say 这就是设置标题的方式。

【问题讨论】:

    标签: ruby-on-rails ruby testing


    【解决方案1】:

    他们的建议转化为以下内容:

    setup do
      @request.env['HTTP_REFERER'] = 'http://test.com/sessions/new'
      post :create, { :user => { :email => 'invalid@abc' } }
    end
    

    【讨论】:

    • 你可以只指定相对路径,就像在'/sessions/new'中一样。
    • 这对我不起作用,因为我使用的是 https => 'on'。现在该怎么办?
    【解决方案2】:

    接受的答案不适用于集成测试,因为 @request 变量不存在。

    根据RailsGuides,您可以将标头传递给助手。

    导轨
    test "blah" do
      get root_path, {}, {'HTTP_REFERER' => 'http://foo.com'}
      ...
    end
    

    导轨 >= 5:

    test "blah" do
      get root_path, params: { id: 12 }, headers: { "HTTP_REFERER" => "http://foo.com" }
      ...
    end
    

    【讨论】:

    • 非常感谢。我搜索了 1 小时的解决方案。你的帖子适合我!
    • 在 Rails 5 上,标头指定为:get :show, params: { id: 12 }, headers: { "HTTP_REFERER" => "http://example.com/home" }source
    【解决方案3】:

    回答问题:

    为什么这不起作用:

    setup { post :create, { :user => { :email => 'invalid@abc' } }, 
    { 'referer' => '/sessions/new' } }
    

    它不起作用,因为 the Rails doc you linked to 记录的类与您可能正在使用的类不同。

    您链接到ActionController::Integration:Session。我猜您正在编写功能测试(如果您使用 Test::Unit)或控制器测试(如果您使用 Rspec)。无论哪种方式,您都可能使用ActionController::TestCase 或其子类。其中又包含模块ActionController::TestProcess

    ActionController::TestProcess 提供了一个get 方法,其参数与ActionController::Integration:Session 提供的get 方法不同。 (烦人,嗯?)方法签名是这样的:

     def get(action, parameters = nil, session = nil, flash = nil)
    

    遗憾的是,没有 headers 参数。但至少设置@request.env['HTTP_REFERER'] 有效。

    【讨论】:

      【解决方案4】:

      在 Rails3 中我遇到了同样的错误:
      为了在相应的控制器中消除此问题,为“redirect_to :back”提供了救援

      示例:redirect_to :back rescue redirect_to required_path

      【讨论】:

        【解决方案5】:
        setup do
          @request.env['HTTP_REFERER'] = 'http://test.com/sessions/new'
          post :create, { :user => { :email => 'invalid@abc' } }
        end
        

        在 Rails 2.2.2 中,上述代码块从未运行过实际测试。这么说

        post :create, { :user => { :email => 'invalid@abc' } }

        线路没有运行。您可以简单地摆脱设置块并使用

        @request.env['HTTP_REFERER'] = 'http://test.com/sessions/new'
        post :create, { :user => { :email => 'invalid@abc' } }
        

        相反。它应该设置引用者

        【讨论】:

          【解决方案6】:

          对上述问题最直接的解决方案是使用关联的标头发出请求。 Rails 会自动读取这个标题。

          post '/your-custom-route', {}, {'HTTP_REFERER': 'http://www.your-allowed-domain.com'}
          

          【讨论】:

            【解决方案7】:

            目前,我使用的是 Rails 5.2.1,我在控制器内的 stub request referer 方法如下:

            let(:stub_referer) { some_path(some_param) }
            before do
              request.headers.merge! referer: stub_referer
              get :some_action, format: :html
            end
            

            【讨论】:

              猜你喜欢
              • 2012-08-01
              • 2021-09-20
              • 2012-12-09
              • 1970-01-01
              • 2013-10-19
              • 2019-08-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多