7

我想知道如何简单地允许所有异常在请求规范中间冒泡到 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?

谢谢!

4

2 回答 2

2

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

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

考虑一下当你手动测试这样的东西时会发生什么。当您转到特定(损坏的)URL 时,浏览器中会显示什么?两件事之一:

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

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

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

该规范本质上是在做同样的事情,但是是自动化的。该visit()调用运行良好,并且确实生成某种 HTML 页面。然后,测试会尝试通过单击链接来验证其中是否包含某些特定内容,这就是测试失败的地方。这一步在概念上与您说“嘿!”相同。仅在页面加载并且不包含您期望的内容之后。

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

功能测试:

  • what:页面不包含预期的内容
  • 为什么:控制器操作引发错误

单元测试:

  • what : 控制器动作抛出了一个错误
  • 为什么:有人忘记将该文件放入项目(或其他)
于 2012-08-22T22:07:21.120 回答
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

于 2012-12-02T23:03:07.403 回答