如何允许例外在rspec请求规范中冒泡

时间:2012-08-22 20:49:34

标签: ruby-on-rails-3 rspec

我想知道如何在请求规范的中间简单地允许所有异常冒泡到rspec。

我希望一个例子可以说明这一点。假设我有以下请求规范和相应的应用程序代码:

# user_browses_posts_spec.rb
feature 'User views a post' do
  scenario 'this should fail with route missing' do
    FactoryGirl.create(:post)
    visit(root_path)
    click_on('View Post')
  end
end

# config/routes.rb
MyApp::Application.routes.draw do
  root to: 'posts#index'
  # notice I have not defined a :posts resource, so post_path should raise NoMethodError
end

# assume a totally standard app/controllers/posts_controller.rb

# app/views/posts/index.html.erb
<% @posts.each do |post| %>
  <%= link_to 'View Post', post_path(post) %>  # this line should fail
<% end %>

当我进行测试时,我看到的是:

Failure/Error: click_on('View Post')
Capybara::ElementNotFound:
  no link or button 'View Post' found

这是因为当从应用程序中引发NoMethodError时,规范运行器没有察觉到问题,因为它看到了正常的Rails开发错误页面(包含错误消息,回溯,参数等)。

但我想要在我的终端中看到的是:

Failure/Error: visit(root_path)
NoMethodError:
  undefined method `post_path' for #<PostsController:0x007fea60a779c8>

那么,我的问题是如何完全禁用rails错误处理,所以NoMethodError会一直冒泡到rspec?

谢谢!

2 个答案:

答案 0 :(得分:2)

我不相信这是可能的。但是,我也不认为你真的希望visit()冒出控制器错误,即使它可能,因为visit()用于功能测试。

请求规范在他们自己的上下文中运行,这意味着visit()方法会像访问浏览器一样访问URL,而不是直接调用控制器方法。因此,请求将通过所有Rack中间件和Rails路由层。那里的错误处理行为与现实世界中的错误处理相同,这对于像这样的“功能”测试来说是一件好事。

考虑手动测试此类内容时会发生什么。当您转到特定(损坏)的URL时,浏览器中会显示什么?两件事之一:

  • 在制作中,它通常是一个静态错误页面
  • 在开发中,生成的页面包含描述错误的文本(带有堆栈跟踪)

在这两种情况下,浏览器实际上都会收到一个HTML页面。

接下来,你看看这个页面并对自己说“嘿,这不是我期待的页面!”。此时,您已确定 出错了什么:页面不是您所期望的。然后,您必须调查日志,或者阅读开发模式错误页面上的堆栈跟踪,以尝试确定为什么出错。

规范本质上是做同样的事情,但是自动化。 visit()调用工作正常,它确实生成了某些类型的HTML页面。然后,测试通过尝试单击链接来尝试验证这包含某些特定内容,这是测试失败的地方。这个步骤在概念上与你说的“嘿!”相同。只有在页面加载后它才包含您所期望的内容。

如果您愿意,可以直接对控制器方法进行单元测试。这些将告诉你 在更细微的层面上出错了什么。

功能测试:

  • 内容:该网页未包含预期内容
  • 为什么:控制器操作引发了错误

单元测试:

  • 内容:控制器操作引发了错误
  • 为什么:有人忘记将该文件放入项目中(或其他任何内容)

答案 1 :(得分:0)

你可以这样做:

expect { visit(root_path) }.to raise_exception

您还可以指定特定的例外,请参阅https://www.relishapp.com/rspec/rspec-expectations/v/2-12/docs/built-in-matchers/raise-error-matcher