1

看起来要么我错过了一些非常基本的东西,要么 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 ”?

4

3 回答 3

4

正如@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

这就是工作。

于 2014-11-04T10:39:52.677 回答
3

你的测试是错误的。

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

期望(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,因为您得到的是模拟而不是真实的响应。

于 2014-10-31T13:43:21.523 回答
1

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

于 2018-12-27T14:42:13.087 回答