Testing Routes
Let's check out our app. Run bundle exec rails s
in your console and go to localhost:3000
in the browser. Right now we have a generic landing page. Let's change that!
Now let's run our tests and see if anything is failing or pending... oh look -- two pending tests!
spec/routing/application_routing_spec.rb
spec/requests/application_spec.rb
Let's add a basic routing expectation to our pended routing test.
# in spec/routing/application_routing_spec.rb
RSpec.describe ApplicationController, type: :routing do
describe "Basic application routing" do
it "routes to #index" do
expect(:get => "/home").to route_to("application#home")
end
end
end
Run your test
Alright, we have a failure to chase! Looks like our application#home route is missing. Let's add that to our config/routes.rb
file.
# in config/routes.rb
Rails.application.routes.draw do
get '/home', to: 'application#home', as: 'home'
end
Run tests... woo hoo they pass!
Check out the app
That seemed a little too easy. Let's verify that this route works in the the browser. Reboot your server and navigate to localhost:3000/home
Womp womp! Our tests were passing but our app doesn't work.
Reproduce our app failure in test
Perhaps our requests test will help us reproduce. Navigate to spec/requests/application_spec.rb
and let's add an expectation.
# in spec/requests/application_spec.rb
require 'rails_helper'
RSpec.describe "Application", type: :request do
describe "GET /home" do
it "successfully gets the home page" do
get home_path
expect(response).to have_http_status(200)
end
end
end
Now run your tests again... Woo hoo, we reproduced the failure!
Failures:
1) Application GET /home works! (now write some real specs)
Failure/Error: get home_path
AbstractController::ActionNotFound:
The action 'home' could not be found for ApplicationController
# ./spec/requests/application_spec.rb:6:in `block (3 levels) in <top (required)>'
Finished in 0.19381 seconds (files took 1.75 seconds to load)
11 examples, 1 failure
Chase the failures
Now let's add our controller....
Add the following to your application controller
# in app/controllers/application.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def home
end
end
Run your tests... do they pass? Still no...
Failures:
1) Application GET /home successfully gets the home page
Failure/Error: get home_path
ActionController::UnknownFormat:
ApplicationController#home is missing a template for this request format and variant.
request.formats: ["text/html"]
request.variant: []
NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you're loading it in a web browser, we assume that you expected to actually render a template, not nothing, so we're showing an error to be extra-clear. If you expect 204 No Content, carry on. That's what you'll get from an XHR or API request. Give it a shot.
# ./spec/requests/application_spec.rb:6:in `block (3 levels) in <top (required)>'
Finished in 0.33427 seconds (files took 2.43 seconds to load)
11 examples, 1 failure
Looks like we're missing a view. Let's add an application
folder under app/views
and add a home.html.erb
file there.
mkdir app/views/application
touch app/views/application/home.html.erb
Run our test again, and it passes!
Solutions branch
git checkout testing_routing_solutions