【问题标题】:How to test render status: 404 with Rails4 and RSpec when using rescue_from如何测试渲染状态:Rails4 和 RSpec 使用 rescue_from 时出现 404
【发布时间】:2013-08-04 07:07:38
【问题描述】:

我有一个带有“PagesController”的 Rails4 应用程序。

当找不到页面时,show-method 会引发自定义异常“PageNotFoundError”。

在我定义的控制器之上 rescue_from PageNotFoundError, with: :render_not_found

render not foundPagesController 的私有方法,看起来像:

def render_not_found
  flash[:alert]=t(:page_does_not_exists, title: params[:id])
  @pages = Page.all
  render :index, status: :not_found #404
end

开发模式下的rails-log显示:

Started GET "/pages/readmef" for 127.0.0.1 at 2013-08-02 23:11:35 +0200
Processing by PagesController#show as HTML
  Parameters: {"id"=>"readmef"}
  ..
  Completed 404 Not Found in 14ms (Views: 12.0ms)

所以,到目前为止,它连接了我的 :status => :not_found 作品。

当我做curl -v http://0.0.0.0:3000/pages/readmef curl 日志时

curl -v http://localhost:3000/pages/readmef
* About to connect() to localhost port 3000 (#0)
*   Trying 127.0.0.1...
* connected
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /pages/readmef HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8x zlib/1.2.5
> Host: localhost:3000
> Accept: */*
>
< HTTP/1.1 404 Not Found
< X-Frame-Options: SAMEORIGIN

但使用 RSpec 进行的以下测试失败:

 it 'renders an error if page not found' do
    visit page_path('not_existing_page_321')
    expect(response.status).to eq(404)
    within( '.alert-error' ) do
      page.should have_content('Page not_existing_page_321 doesn\'t exist')
    end
  end

  1) PagesController renders an error if page not found
     Failure/Error: expect(response.status).to eq(404)

       expected: 404
            got: 200

一切看起来都很好,甚至 test.log 也显示 404

$ tail -f log/test.log
Started GET "/pages/not_existing_page_321" for 127.0.0.1 at 2013-08-03 09:48:13 +0200
Processing by PagesController#show as HTML
  Parameters: {"id"=>"not_existing_page_321"}
  Rendered pages/_page.haml (0.8ms)
  Rendered layouts/_navigation.haml (0.6ms)
  Rendered layouts/_messages.haml (0.2ms)
  Rendered layouts/_locales.haml (0.3ms)
  Rendered layouts/_footer.haml (0.6ms)
Completed 404 Not Found in 6ms (Views: 4.5ms)

我尝试了不同的服务器、WebRICK、Thin、独角兽。在开发和生产模式下,一切都按预期工作。即使 test.log 是正确的,但测试失败。

谁能告诉我为什么测试显示的是 200 而不是 404?

【问题讨论】:

  • 你卷曲了pages/readme,而不是pages/readmef。而且你还没有包含你的测试代码。
  • blushing @sevenseacat 你的权利我没有看到 curl 命令中缺少 f 。确实 curl 工作正常并以 404 响应。_我真的应该戴上我的眼镜:/ 但规范仍然不起作用。我已经在上面添加了。
  • @sevenseacat 感谢您的评论。它把我引向了真正的问题。我再次提出了这个问题。

标签: ruby-on-rails rspec http-response-codes


【解决方案1】:

虽然我对这个解决方案不太满意,但至少这是一种解决方法:

我将测试分为两个单独的规范。一个用于测试响应代码 404(使用 GET 而不是访问),另一个用于测试警报。第二个测试是必要的,因为 get 不会渲染视图 - 即使 render_views 是在规范文件顶部定义的。

  it 'response with 404 if page not found' do
    get :show, { controller: 'pages', id: 'not_existing_page_321' }
    expect(response.status).to eq(404)
  end

  it 'renders an error-message if page not found and shows index' do
    visit page_path('page_not_found')
    within '.alert-error' do
      page.should have_content("Page page_not_found doesn't exist")
    end
  end

【讨论】:

  • @Luca Spiller 是正确的,您的解决方案也是正确的。
【解决方案2】:

这里的问题是您混淆了 Capybara 功能测试和 RSpec 控制器测试。 visit 是 Capybara 提供的方法,get / response 是 RSpec 控制器测试提供的 - 不能一起使用

要将其作为单个 RSpec 控制器测试进行测试,您可以执行以下操作:

it "returns a not found response" do
  get :show, { id: 'not_existing_page_321' }
  expect(response.status).to eq(404)
  expect(response.text).to match(/Page page_not_found doesn't exist/)
end

(注意,get 行与您发布的不同 - 我没有包含 controller 参数,就好像您将它放在它所属的 spec/controllers/pages_controller_spec.rb 中一样,您不需要它)

或者作为单个 Capybara 功能测试:

it "renders a not found response" do
  visit page_path('page_not_found')
  expect(page.status_code).to eq(404)
  within '.alert-error' do
    expect(page).to have_content("Page page_not_found doesn't exist")
  end
end

【讨论】:

    【解决方案3】:

    RSpec 3+ 的另一种方法是测试异常:

    it 'responds with a 404 if the page is not found' do
      expect { get(:show, id: 'bad_id') }.to raise_error(ActionController::RoutingError)
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多