2012-01-29 17 views
6

के लिए नियंत्रक की कार्रवाई बनाने के लिए आरएसपीसी परीक्षण मेरे पास एक रेल एप्लिकेशन (रेल 3.0.10) है जहां उपयोगकर्ता कई लेख प्राप्त कर सकते हैं, और जहां उपयोगकर्ता लेखों पर टिप्पणियां छोड़ सकते हैं। लेख शो पेज पर टिप्पणियां की जाती हैं।एक नेस्टेड संसाधन

अब मैं टिप्पणियाँ नियंत्रक की निर्माण कार्य का परीक्षण करना चाहता हूं, हालांकि, मुझे सही पैरामीटर के साथ पोस्ट विधि का आह्वान करने की समस्याएं हैं।

यहाँ CommentsController का कोड है:

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 

दोनों परीक्षण असफल, तथापि, के कारण:

class CommentsController < ApplicationController 

    # create a comment and bind it to an article and a user 
    def create 
    @article = Article.find(params[:article_id]) 
    @user = User.find(@article.user_id) 
    @comment = @article.comments.build(params[:comment]) 
    @comment.user_id = current_user.id 

    commenters = [] 
    @article.comments.each { 
     |comment| 
     commenters << User.find(comment.user_id) 
    } 
    commenters.uniq! 

    respond_to do |format| 
     if @comment.save   

     #Notify user who offers article on new comment, else notify the commenters 
     if @article.user_id != @comment.user_id 
      UserMailer.new_article_comment_email(@user, @comment).deliver 
     else   
      commenters.each { 
      |commenter| 
      UserMailer.new_article_comment_email(commenter, @comment).deliver 
      } 
     end 

     format.html { 
      redirect_to(@article) 
      flash[:notice] = t(:comment_create_success) 
     } 
     else 
     format.html { 
      redirect_to(@article) 
      flash[:error] = t(:comment_create_error) 
     } 
     end 
    end 
    end 
end 

इस कार्रवाई (कुछ प्रयोग अब तक) के परीक्षण के लिए RSpec कोड पीछा कर रहा है अलग-अलग कारण जिन्हें मैं ठीक करने में असमर्थ हूं:

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"} 
     # ./spec/controllers/comments_controller_spec.rb:22:in `block (4 levels) in <top (required)>' 
     # ./spec/controllers/comments_controller_spec.rb:21:in `block (3 levels) in <top (required)>' 

     2) CommentsController POST 'create' should create a new comment, redirect to the article show page of this comment and notify the user on successful saving of the comment 
     Failure/Error: post :create, :comment => @comment_attributes, :article_id => @article.id.to_s, :user_id => @user.id.to_s 
     RuntimeError: 
      Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id 
     # ./app/controllers/comments_controller.rb:8:in `create' 
     # ./spec/controllers/comments_controller_spec.rb:27:in `block (3 levels) in <top (required)>' 

यदि मैं महान होगा तो मैं बहुत अच्छा होगा कोई मेरी मदद कर सकता है। अग्रिम में धन्यवाद!

अद्यतन:

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's 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"} 

अपडेट:: यहाँ routes.rb मैं उपयोग कर रहा हूँ है

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 

और टिप्पणी के लिए FactoryGirl परिभाषा:: यहाँ संशोधन मैं nmotts सुझाव के अनुसार था

factory :comment do 
    body "This is the body text of a comment" 
    article 
end 

दुर्भाग्यवश, कोड अभी तक काम नहीं कर रहा है।

+0

कृपया अपने मार्ग पोस्ट करें।आरबी – lucapette

+0

मैंने अपनी पोस्ट को पूर्ण मार्गों के साथ अपडेट किया। आरबी –

उत्तर

18

एक नेस्टेड संसाधन के लिए आपको बच्चे की टिप्पणी पोस्ट करते समय मूल लेख की पहचान करने के लिए सेटअप डेटा और पोस्ट को इस तरह से बनाने की आवश्यकता है।

एक दृष्टिकोण फैक्ट्री गर्ल एसोसिएशन को सही तरीके से स्थापित करना है और फिर यह सुनिश्चित करना है कि बच्चे के गुण बनाने के दौरान मूल तत्व सेट किया गया हो। यह कुछ इस तरह दिखेगा:

टिप्पणी कारखाने में:

FactoryGirl.define do 
    Factory :comment do 
    comment "My comment" 
    article 
    end 
end 

लेख बुला, और वहाँ एक वैध :article कहा जाता है तो FactoryGirl जब एक टिप्पणी बनाई गई है एक लेख पैदा करेगा कारखाना है सुनिश्चित करें कि करके। परीक्षणों को अच्छी तरह से प्रवाह करने के लिए हमें वास्तव में विशिष्ट होना चाहिए कि article का उपयोग तब किया जाता है जब comment बनाया गया है, इसलिए अब फैक्ट्री जगह पर है, हम spec में निम्नलिखित का उपयोग करते हैं।

@comment_attributes = FactoryGirl.attributes_for(:comment, :article_id => @article) 

यह टिप्पणी विशेषताओं को बनाएगा जो स्वचालित रूप से @article से जुड़े हुए हैं। आखिरी टुकड़ा तब पोस्ट का निर्माण करने के लिए है, यह सुनिश्चित कर लें कि हम माता-पिता और बच्चे को शामिल करें।

जब एक नेस्टेड संसाधन पोस्ट किया जाता है तो यह माता-पिता संसाधन और बच्चे दोनों के लिए पैरा की अपेक्षा करता है। आरएसपीईसी में हम इसे निम्न पद में निम्नानुसार प्रदान कर सकते हैं:

post :create, :article_id => @article, :comment => @comment_attributes 

यह सभी टुकड़ों को सही ढंग से जोड़ना चाहिए।

+0

धन्यवाद एनएमओटी, आपकी स्पष्टीकरण के साथ चीजें मुझे स्पष्ट करती हैं। दुर्भाग्यवश, यह अभी तक काम नहीं कर सका। मैंने उपरोक्त आपकी सिफारिशों के अनुसार अपने परिवर्तन पोस्ट किए हैं। –

+0

ठीक है, मुझे अब यह काम मिल गया है। समस्या यह थी कि केवल साइन इन उपयोगकर्ता टिप्पणी कर सकते हैं। समस्या इस प्रकार न केवल नेस्टेड नियंत्रक का परीक्षण कैसे किया गया था, लेकिन परीक्षण उपयोगकर्ता बनाने और नेस्टेड टिप्पणी नियंत्रक का परीक्षण करने से पहले उपयोगकर्ता को लॉग इन करना आवश्यक था। –