【问题标题】:Rspec testing redirect_to :backRspec 测试 redirect_to :back
【发布时间】:2011-08-27 18:47:31
【问题描述】:

如何在 rspec 中测试 redirect_to :back

我明白了

ActionController::RedirectBackError:
此操作的请求中未设置HTTP_REFERER,因此无法成功调用redirect_to :back。如果这是一个测试,请确保指定request.env["HTTP_REFERER"]

如何在我的测试中设置HTTP_REFERER

【问题讨论】:

  • 查看测试源本身可能很有用。这可能是另一个问题的征兆...
  • 我可以通过先调用“访问根路径”来缓解这个错误。但我认为我只能在集成测试中做到这一点。对吗?

标签: ruby-on-rails redirect rspec rspec2


【解决方案1】:

使用 RSpec,您可以在 before 块中设置引用者。当我尝试在测试中直接设置referer时,无论我把它放在哪里,它似乎都不起作用,但是 before 块可以解决问题。

describe BackController < ApplicationController do
  before(:each) do
    request.env["HTTP_REFERER"] = "where_i_came_from"
  end

  describe "GET /goback" do
    it "redirects back to the referring page" do
      get 'goback'
      response.should redirect_to "where_i_came_from"
    end
  end
end

【讨论】:

  • 我发现这是个好主意:request.env["HTTP_REFERER"] = "where_i_came_from" unless request.nil? or request.env.nil?
  • 是的。对我来说,它总是零,它只是不工作。对我来说看起来像一个巨大的错误。
  • 自创建此答案以来,它可能已更新以解决此问题,但我能够在我的测试中成功设置 request.env["HTTP_REFERER"] 而无需使用 before 块。
【解决方案2】:

rails guide 请求新请求样式的请求时:

describe BackController < ApplicationController do
  describe "GET /goback" do
    it "redirects back to the referring page" do
      get :show, 
        params: { id: 12 },
        headers: { "HTTP_REFERER" => "http://example.com/home" }
      expect(response).to redirect_to("http://example.com/home")
    end
  end
end

【讨论】:

    【解决方案3】:

    如果有人偶然发现了这一点并且他们正在使用request 规范,那么您需要在您发出的请求中明确设置标头。测试请求的格式取决于您使用的 RSpec 版本以及是否可以使用关键字参数而不是位置参数。

    let(:headers){ { "HTTP_REFERER" => "/widgets" } }
    
    it "redirects back to widgets" do 
      post "/widgets", params: {}, headers: headers # keyword (better)
      post "/widgets", {}, headers                  # positional
    
      expect(response).to redirect_to(widgets_path)
    end
    

    https://relishapp.com/rspec/rspec-rails/docs/request-specs/request-spec

    【讨论】:

      【解决方案4】:

      恕我直言,接受的答案有点老套。更好的选择是将HTTP_REFERER 设置为应用程序中的实际网址,然后期望被重定向回来:

      describe BackController, type: :controller do
        before(:each) do
          request.env['HTTP_REFERER'] = root_url
        end
      
        it 'redirects back' do
          get :whatever
          response.should redirect_to :back
        end
      end
      
      • 重定向到一个随机字符串常量感觉就像是偶然发生的一样
      • 您可以利用 rspec 的内置功能准确表达您想要的内容
      • 您不会引入和重复魔术字符串值

      对于较新版本的 rspec,您可以改用期望:

      expect(response).to redirect_to :back
      

      【讨论】:

        【解决方案5】:

        关于在集成测试中测试 :back 链接,我首先访问一个死端页面,我认为它不太可能被用作链接,然后是我正在测试的页面。所以我的代码是这样的

           before(:each) do
               visit deadend_path
               visit testpage_path
            end
            it "testpage Page should have a Back button going :back" do
              response.should have_selector("a",:href => deadend_path,
                                                :content => "Back")
            end
        

        但是这确实有一个缺陷,如果链接真的是到 deadend_path,那么测试将错误地通过。

        【讨论】:

          【解决方案6】:
          request.env['HTTP_REFERER'] = '/your_referring_url'
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-10-23
            • 1970-01-01
            • 2017-10-21
            • 1970-01-01
            • 2013-05-27
            • 1970-01-01
            • 1970-01-01
            • 2014-05-13
            相关资源
            最近更新 更多