I want to know how to simply allow all exceptions to bubble up to rspec in the middle of a request spec.
I hope an example will make this clear. Let's say I have the following request spec and corresponding application code:
# 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 %>
When I run the test, what I see is:
Failure/Error: click_on('View Post')
Capybara::ElementNotFound:
no link or button 'View Post' found
This is because when the NoMethodError was raised from within the app, the spec runner did not perceive a problem because it saw the normal Rails development error page (with the error message, backtrace, params, etc).
But what I want to see in my terminal is:
Failure/Error: visit(root_path)
NoMethodError:
undefined method `post_path' for #<PostsController:0x007fea60a779c8>
My question, then, is how can I disable that rails error handling entirely, so the NoMethodError bubbles all the way up to rspec?
Thanks!
RSpec is a testing framework written in Ruby to test Ruby code. To get started using RSpec with Rails, add it to the Gemfile. group :development, :test do gem 'rspec-rails' end. Next finish setting it up by running bundle install in your project directory and then. rails generate rspec:install.
I don't believe this is possible. However, I also don't think you'd really want visit() to bubble up controller errors even if it could, since visit() is intended for functional testing.
Request specs run in their own context, meaning that the visit()
method hits the URL as if it were a browser, rather than calling the controller method directly. Thus, the request will go through all the Rack middleware and the Rails routing layer. The error handling there behaves the same as it would in the real world, which is a good thing for 'functional' tests like these.
Consider what happens when you manually test something like this. When you go to a specific (broken) URL, what shows up in the browser? One of two things:
In both cases the browser does, in fact, receive an HTML page.
Next, you look at this page and say to yourself "Hey, that's not the page I was expecting!". At this point, you've determine what went wrong: the page isn't what you expected. You'd then have to investigate in the logs, or read the stack trace on the development mode error page, to try to determine why this went wrong.
The spec is essentially doing the same thing, but automated. The visit()
call worked just fine, and it did produce some kind of HTML page. The test then tries to validate that this contains some specific content by trying to click a link, and this is where the test fails. This step is conceptually the same as you saying "Hey!" only after the page has loaded and it doesn't contain what you expected.
You can unit test the controller methods directly if you'd like. Those will tell you what went wrong at a much more granular level.
Functional test:
Unit test:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With