ruby-on-rails-4url-routingrake-testruby-test

ruby rails test case failing but real app works


So here's a strange problem: When I start my local rails app and browse to http://localhost:3000/static_pages/help I can see the page I created there. However, the test case that I wrote says otherwise.

static_pages_controller_test.rb

require 'test_helper'

class StaticPagesControllerTest < ActionController::TestCase
  test "should get home" do
    get :home
    assert_response :success
  end

  test "should get help" do
    puts static_pages_help_url
    puts static_pages_help_path
    get static_pages_help_url
    assert_response :success
  end    

end

It fails with this error, Output of $bin/rake test:

 Running:

..http://test.host/static_pages/help
/static_pages/help
E

Finished in 0.466745s, 8.5700 runs/s, 4.2850 assertions/s.

  1) Error.

StaticPagesControllerTest#test_should_get_help:
ActionController::UrlGenerationError: No route matches {:action=>"http://test.host/static_pages/help", :controller=>"static_pages"}
    test/controllers/static_pages_controller_test.rb:12:in `block in <class:StaticPagesControllerTest>'

Here is routes.rb

Rails.application.routes.draw do
  get 'static_pages/home'

  get "static_pages/help"
end

and here is the static_pages_controller.rb

class StaticPagesController < ApplicationController
  def home
  end

  def help
  end
end

and these two files

app/views/static_pages/home.html.erb
app/views/static_pages/help.html.erb

exist, as I can also see them when navigating to /static_pages/help in my browser. I've searched the web for hours, no clue.

$ rails --version
Rails 4.2.7.1
$ ruby --version
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]

I must be missing something. Please help.


Solution

  • Since you're writing a controller spec, the parameter to a GET should be the action(controller method). But you're passing a URL. If you look at the error message, you can find that "http://test.host/static_pages/help" was passed into action. So, pass the name of the controller method as a symbol rather than the URL. Try

    get :help
    

    Note that help is the controller action.

    However if you're interested in writing an integration test, you should inherit from ActionDispatch::IntegrationTest rather than ActionController::TestCase. So, your spec should look aomething like this.

    class StaticPagesControllerTest < ActionDispatch::IntegrationTest
      test "should get home" do
        get static_pages_home_url
        assert_response :success
      end
    
      test "should get help" do
        get static_pages_help_url
        assert_response :success
      end        
    end
    

    To learn more about integration and controller tests, see http://weblog.jamisbuck.org/2007/1/30/unit-vs-functional-vs-integration.html

    Hope this helps!