我想知道如何简单地允许所有异常在请求规范的中间冒泡到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?
谢谢!
最佳答案 我不相信这是可能的.但是,我也不认为你真的希望visit()冒出控制器错误,即使它可能,因为visit()用于功能测试.
请求规范在它们自己的上下文中运行,这意味着visit()方法像访问浏览器一样访问URL,而不是直接调用控制器方法.因此,请求将通过所有Rack中间件和Rails路由层.那里的错误处理行为与现实世界中的错误处理相同,这对于像这样的“功能”测试来说是一件好事.
考虑一下手动测试这样的事情会发生什么.当您转到特定(损坏)的URL时,浏览器中会显示什么?两件事之一:
>在生产中,它通常是一个静态错误页面
>在开发中,生成的页面包含描述错误的文本(带有堆栈跟踪)
在这两种情况下,浏览器实际上都会收到一个HTML页面.
接下来,你看看这个页面并对自己说“嘿,这不是我期待的页面!”.此时,您已确定出现了什么问题:页面不是您所期望的.然后,您必须调查日志,或者在开发模式错误页面上读取堆栈跟踪,以尝试确定出错的原因.
该规范本质上是做同样的事情,但自动化. visit()调用工作得很好,它确实产生了某种HTML页面.然后,测试通过尝试单击链接来尝试验证这包含某些特定内容,这是测试失败的地方.这个步骤在概念上与你说的“嘿!”相同.只有在页面加载后它才包含您所期望的内容.
如果您愿意,可以直接对控制器方法进行单元测试.这些将告诉你在更细粒度的水平上出了什么问题.
功能测试:
> what:页面中没有包含预期的内容
>为什么:控制器动作引发了错误
单元测试:
>什么:控制器动作引发了错误
>为什么:有人忘记将该文件放入项目中(或其他)