I have a Rails application (Rails 3.0.10) where users can have many articles and where users can post comments. Comments are made on the article page.
Now I want to check the create commentController action, however I am having problems calling the post method with the correct parameters.
Here's the comment code of the Controller:
class CommentsController < ApplicationController
RSpec code to test this action (some experiments so far):
require 'spec_helper' require 'ruby-debug' describe CommentsController do render_views describe "POST 'create'" do before(:each) do @user = FactoryGirl.create(:user) @article = FactoryGirl.build(:article) @article.user_id = @user.id @article.save @article_attributes = FactoryGirl.attributes_for(:article) @comment_attributes = FactoryGirl.attributes_for(:comment) end it "should create a new comment" do expect { post :create, :comment => @comment_attributes }.to change(Comment, :count).by(1) end it "should create a new comment, redirect to the article show page of this comment and notify the user on successful saving of the comment" do post :create, :comment => @comment_attributes, :article_id => @article.id.to_s, :user_id => @user.id.to_s flash[:notice].should_not be_nil response.should redirect_to(article_path(@article)) end end end
Both tests do not work, however due to various reasons that I cannot fix:
Failures: 1) CommentsController POST 'create' should create a new comment Failure/Error: post :create, :comment => @comment_attributes ActionController::RoutingError: No route matches {:comment=>{:body=>"This is the body text of a comment"}, :controller=>"comments", :action=>"create"}
It would be great if someone could help me. Thanks in advance!
Update: here route.rb I use:
Cinderella::Application.routes.draw do # The priority is based upon order of creation: # first created -> highest priority. # Sample of regular route: # match 'products/:id' => 'catalog#view' # Keep in mind you can assign values other than :controller and :action # Sample of named route: # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase # This route can be invoked with purchase_url(:id => product.id) match '/signup', :to => 'users#new' match '/signin', :to => 'sessions#new' match '/signout', :to => 'sessions#destroy' match '/home', :to => 'pages#home' match '/about', :to => 'pages#about' match '/faq', :to => 'pages#faq' match '/howitworks_sellers', :to => "pages#howitworks_sellers" match '/howitworks_buyers', :to => "pages#howitworks_buyers" match '/contact', :to => 'pages#contact' match '/articles/:id/ratings', :to => 'ratings#destroy' # Sample resource route (maps HTTP verbs to controller actions automatically): # resources :products resources :articles do resources :comments, :only => [:create, :destroy] end resources :ratings resources :ratings do collection do post 'destroy' end end resources :users do resources :articles end resources :sessions, :only => [:new, :create, :destroy] # Sample resource route with options: # resources :products do # member do # get 'short' # post 'toggle' # end # # collection do # get 'sold' # end # end # Sample resource route with sub-resources: # resources :products do # resources :comments, :sales # resource :seller # end # Sample resource route with more complex sub-resources # resources :products do # resources :comments # resources :sales do # get 'recent', :on => :collection # end # end # Sample resource route within a namespace: # namespace :admin do # # Directs /admin/products/* to Admin::ProductsController # # (app/controllers/admin/products_controller.rb) # resources :products # end # You can have the root of your site routed with "root" # just remember to delete public/index.html. root :to => "pages#home" # See how all your routes lay out with "rake routes" # This is a legacy wild controller route that not recommended for RESTful applications. # Note: This route will make all actions in every controller accessible via GET requests. # match ':controller(/:action(/:id(.:format)))' end #== Route Map # Generated on 14 Dec 2011 14:24 # # signin /signin(.:format) {:controller=>"sessions", :action=>"new"} # signout /signout(.:format) {:controller=>"sessions", :action=>"destroy"} # home /home(.:format) {:controller=>"pages", :action=>"home"} # about /about(.:format) {:controller=>"pages", :action=>"about"} # faq /faq(.:format) {:controller=>"pages", :action=>"faq"} # articles GET /articles(.:format) {:action=>"index", :controller=>"articles"} # POST /articles(.:format) {:action=>"create", :controller=>"articles"} # new_article GET /articles/new(.:format) {:action=>"new", :controller=>"articles"} # edit_article GET /articles/:id/edit(.:format) {:action=>"edit", :controller=>"articles"} # article GET /articles/:id(.:format) {:action=>"show", :controller=>"articles"} # PUT /articles/:id(.:format) {:action=>"update", :controller=>"articles"} # DELETE /articles/:id(.:format) {:action=>"destroy", :controller=>"articles"} # user_articles GET /users/:user_id/articles(.:format) {:action=>"index", :controller=>"articles"} # POST /users/:user_id/articles(.:format) {:action=>"create", :controller=>"articles"} # new_user_article GET /users/:user_id/articles/new(.:format) {:action=>"new", :controller=>"articles"} # edit_user_article GET /users/:user_id/articles/:id/edit(.:format) {:action=>"edit", :controller=>"articles"} # user_article GET /users/:user_id/articles/:id(.:format) {:action=>"show", :controller=>"articles"} # PUT /users/:user_id/articles/:id(.:format) {:action=>"update", :controller=>"articles"} # DELETE /users/:user_id/articles/:id(.:format) {:action=>"destroy", :controller=>"articles"} # users GET /users(.:format) {:action=>"index", :controller=>"users"} # POST /users(.:format) {:action=>"create", :controller=>"users"} # new_user GET /users/new(.:format) {:action=>"new", :controller=>"users"} # edit_user GET /users/:id/edit(.:format) {:action=>"edit", :controller=>"users"} # user GET /users/:id(.:format) {:action=>"show", :controller=>"users"} # PUT /users/:id(.:format) {:action=>"update", :controller=>"users"} # DELETE /users/:id(.:format) {:action=>"destroy", :controller=>"users"} # sessions POST /sessions(.:format) {:action=>"create", :controller=>"sessions"} # new_session GET /sessions/new(.:format) {:action=>"new", :controller=>"sessions"} # session DELETE /sessions/:id(.:format) {:action=>"destroy", :controller=>"sessions"} # root /(.:format) {:controller=>"pages", :action=>"home"}
Update: here is the modification I made according to nnotts suggestions:
require 'spec_helper' require 'ruby-debug' describe CommentsController do render_views describe "POST 'create'" do before(:each) do @user = FactoryGirl.create(:user) @article = FactoryGirl.build(:article) @article.user_id = @user.id @article.save @comment_attributes = FactoryGirl.attributes_for(:comment, :article_id => @article) end it "should create a new comment" do post :create, :article_id => @article.id.to_s, :comment => @comment_attributes end end end
And the FactoryGirl definition for comment:
factory :comment do body "This is the body text of a comment" article end
Unfortunately, the code is not working yet.