1
votes

I want to test the permalink action in my articles controller, which is using a named route (/permalink/terms-of-use):

map.permalink 'permalink/:permalink', 
              :controller => :articles, :action => :permalink, :as => :permalink

This is the spec:

describe "GET permalink" do
  it "should visit an article" do
    get "/permalink/@article.permalink"
  end
end

But I get this error:

ActionController::RoutingError in 'ArticlesController permalink renders the page' No route matches {:controller=>"articles", :action=>"/permalink/@article.permalink"}

UPDATE:

any idea how to write the GET?

2

2 Answers

4
votes

The error is because you're passing an entire URL to a method that expects a name of one of the controller's action methods. If I understand correctly, you're trying to test several things at once.

Testing that a route has a name is different from testing a route is different from testing a controller action. Here's how I test a controller action (this probably comes as no surprise). Note that I'm matching your naming, not recommending what I'd use.

In spec/controllers/articles_controller_spec.rb,

describe ArticlesController do
  describe '#permalink' do
    it "renders the page" do
      # The action and its parameter are both named permalink
      get :permalink :permalink => 666
      response.should be_success
      # etc.
    end
  end
end

Here's how I test a named route with only rspec-rails:

In spec/routing/articles_routing_spec.rb,

describe ArticlesController do
  describe 'permalink' do

    it 'has a named route' do
      articles_permalink(666).should == '/permalink/666'
    end

    it 'is routed to' do
      { :get => '/permalink/666' }.should route_to(
        :controller => 'articles', :action => 'permalink', :id => '666')
    end

  end
end

Shoulda's route matcher is more succinct while still providing a nice description and failure message:

describe ArticlesController do
  describe 'permalink' do

    it 'has a named route' do
      articles_permalink(666).should == '/permalink/666'
    end

    it { should route(:get, '/permalink/666').to(
      :controller => 'articles', :action => 'permalink', :id => '666' })

  end
end

AFAIK neither RSpec nor Shoulda have a specific, concise way of testing named routes, but you could write your own matcher.

0
votes
describe "GET permalink" do
  it "should visit an article" do
    get "/permalink/#{@article.permalink}"
  end
end