【问题标题】:How do I use Rack/Test to test Sinatra redirects? The App works, but the test doesn't如何使用 Rack/Test 测试 Sinatra 重定向?该应用程序有效,但测试没有
【发布时间】:2014-10-31 12:47:50
【问题描述】:

看来要么我遗漏了一些非常基本的东西,要么 Rack/Test 无法应对 Sinatra 进行重定向。

大概有办法解决这个问题,否则 Rack/Test 将毫无用处。谁能告诉我我应该怎么做才能让它在这里工作?

(编辑:我最终想要实现的是测试我最终得到哪个页面,而不是状态。在测试中,last_response 对象指向我的应用程序中不存在的页面,并且当然不是你运行它时实际得到的页面。)

一个示例应用:

require 'sinatra'
require 'haml'

get "/" do
  redirect to('/test')
end

get '/test' do
  haml :test
end

这正如您所期望的那样工作。转到“/”或“/test”可以获得views/test.haml的内容。

但是这个测试不起作用:

require_relative '../app.rb'
require 'rspec'
require 'rack/test'

describe "test" do
  include Rack::Test::Methods

  def app
    Sinatra::Application
  end

  it "tests" do
    get '/'
    expect(last_response.status).to eq(200)
  end
end

这是运行测试时发生的情况:

1) test tests
   Failure/Error: expect(last_response.status).to eq(200)

     expected: 200
          got: 302

这就是last_response.inspect 的样子:

#<Rack::MockResponse:0x000000035d0838 @original_headers={"Content-Type"=>"text/html;charset=utf-8", "Location"=>"http://example.org/test", "Content-Length"=>"0", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff", "X-Frame-Options"=>"SAMEORIGIN"}, @errors="", @body_string=nil, @status=302, @header={"Content-Type"=>"text/html;charset=utf-8", "Location"=>"http://example.org/test", "Content-Length"=>"0", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff", "X-Frame-Options"=>"SAMEORIGIN"}, @chunked=false, @writer=#<Proc:0x000000035cfeb0@/home/jonea/.rvm/gems/ruby-1.9.3-p547@sandbox/gems/rack-1.5.2/lib/rack/response.rb:27 (lambda)>, @block=nil, @length=0, @body=[]>

我想知道 Rack/Test 是否刚刚武断地决定在重定向中插入“http://example.org”?

【问题讨论】:

    标签: ruby sinatra rspec2 rack-test


    【解决方案1】:

    正如@sirl33tname 指出的那样,重定向仍然是重定向,所以我可以预期的最佳状态是 302,而不是 200。如果我想测试在重定向结束时是否得到了一个好的页面,我应该测试ok? 不是状态。

    但是,如果我想测试最终得到的 URL,我需要做更多的事情,因为 Rack/Test 基本上是一个模拟系统(原文如此),并在重定向时返回一个页面的模拟,而不是实际页面。

    但事实证明,这很容易被 follow_redirect! 覆盖。

    测试变成:

    it "tests" do
      get '/'
      follow_redirect!
      expect(last_response.status).to be_ok
    
      # ...and now I can test for the contents of test.haml, too...
      expect(last_response.body).to include('foo')
    end
    

    这就是工作。

    【讨论】:

      【解决方案2】:

      你的测试错了。

      重定向的获取是状态码 302。所以正确的测试是:

      expect(last_response.status).to eq(302)

      也许更好的检查方法就是assert last_response.ok?

      http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3

      或者像github的例子:

      get "/"
      follow_redirect!
      
      assert_equal "http://example.org/yourexpecedpath", last_request.url
      assert last_response.ok?
      

      是的,这始终是 example.org,因为您得到的是模拟而不是真实的响应。

      【讨论】:

      • last_response.ok? (expect(last_response).to be(ok)) 也失败了,因为我认为它也在测试状态。
      • 也许我可以更清楚地说明更大的观点——我想测试我最终会得到哪个页面。 Rack/Test 正在返回一些不存在的页面——example.org/test——而不是实际应用程序在运行时重定向到的页面。
      • 为什么?我的理解是您为重定向编写了一个测试,并为实际站点和您的利益编写了一个测试
      • @AndyJones 我同意 l33tname 先生的观点,您无需测试重定向时获得的页面,只需 302 以正确的位置返回即可重定向到。您可以单独测试该位置。
      • @sirl33tname -- 我是 -- 它不起作用 -- 有关更多信息,请重新阅读问题...
      【解决方案3】:

      另一种方法是测试last_response.header['Location']

      【讨论】:

        猜你喜欢
        • 2013-09-01
        • 2012-02-19
        • 2015-12-12
        • 1970-01-01
        • 2011-11-09
        • 1970-01-01
        • 1970-01-01
        • 2011-11-17
        • 1970-01-01
        相关资源
        最近更新 更多