2015-05-09 52 views
0

我已經研究並看到類似的問題(Rspec: Testing nested destroy action),但無法爲我解決問題。在我正在開發的應用程序中,我們有一個Articles模型,用戶可以關注文章。Rspec測試嵌套銷燬行爲以下模型

我已經使用acts_as_follower gem來實現這一點,所以Article模型有一個'追隨者'方法,返回該文章之後的用戶數組。

下面是相關的代碼:

follows_controller

class FollowsController < ApplicationController 
    def create 
    @article = Article.find(params[:article_id]) 
    current_user.follow(@article) 
    redirect_to @article 
    end 

    def destroy 
    @article = Article.find(params[:article_id])  
    current_user.stop_following(@article) 
    redirect_to @article 
    end 
end 

的routes.rb

get '/articles/:id/history', to: 'articles#history', as: :articles_history 
    post '/articles/:id/undo', to: 'articles#undo', as: :undo 
    resources :articles do 
    resources :follows, :only => [:create, :destroy] 
    end 

schema.rb

create_table "follows", force: :cascade do |t| 
    t.integer "followable_id",     null: false 
    t.string "followable_type",     null: false 
    t.integer "follower_id",      null: false 
    t.string "follower_type",     null: false 
    t.boolean "blocked",   default: false, null: false 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

規格/控制器/ follows_controller_spec.rb upda每@下面

describe '#DELETE destroy' do 
it 'deletes a follow' do 
    @article = FactoryGirl.create(:article) 
    follow = FactoryGirl.create(:follow, followable_id: @article.id) 
    # Also, test if the action really deletes a comment. 
    expect{delete :destroy, id: follow.id, article_id: @article.id}. 
    to change{@article.followers.count}.by(-1) 
end 

耙路線彼得的評論特德:

article_follows POST /articles/:article_id/follows(.:format)   follows#create 
article_follow DELETE /articles/:article_id/follows/:id(.:format)  follows#destroy 

這是我得到的運行測試錯誤:

失敗:

1) FollowsController#DELETE destroy deletes a follow 
    Failure/Error: expect{delete :destroy, id: follow.id, followable_id: @article.id}. 
    ActionController::UrlGenerationError: 
     No route matches {:action=>"destroy", :controller=>"follows", :followable_id=>"2", :id=>"2"} 

添加Fac保守黨和基於以下@ PeterAlfvin的建議新的錯誤:

這裏是我廠:

FactoryGirl.define do 
    factory :follow do |f| 
    f.follower_id 1 
    f.followable_id 1 
    f.followable_type "Article" 
    f.follower_type "User" 
    end 
end 

,這裏是當前的錯誤:

1) FollowsController#DELETE destroy deletes a follow 
    Failure/Error: expect{delete :destroy, id: follow.id, article_id: @article.id}. 
    NoMethodError: 
     undefined method `stop_following' for nil:NilClass 
    # ./app/controllers/follows_controller.rb:10:in `destroy' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionpack-4.2.1/lib/action_controller/metal/implicit_render.rb:4:in `send_action' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionpack-4.2.1/lib/abstract_controller/base.rb:198:in `process_action' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionpack-4.2.1/lib/action_controller/metal/rendering.rb:10:in `process_action' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionpack-4.2.1/lib/abstract_controller/callbacks.rb:20:in `block in process_action' 
    # ./.bundle/gems/ruby/2.2.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:117:in `call' 
    # ./.bundle/gems/ruby/2.2.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:117:in `call' 
    # ./.bundle/gems/ruby/2.2.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:555:in `block (2 levels) in compile' 
    # ./.bundle/gems/ruby/2.2.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:505:in `call' 
    # ./.bundle/gems/ruby/2.2.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:505:in `call' 
    # ./.bundle/gems/ruby/2.2.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:92:in `_run_callbacks' 
    # ./.bundle/gems/ruby/2.2.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:776:in `_run_process_action_callbacks' 
    # ./.bundle/gems/ruby/2.2.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:81:in `run_callbacks' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionpack-4.2.1/lib/abstract_controller/callbacks.rb:19:in `process_action' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionpack-4.2.1/lib/action_controller/metal/rescue.rb:29:in `process_action' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionpack-4.2.1/lib/action_controller/metal/instrumentation.rb:32:in `block in process_action' 
    # ./.bundle/gems/ruby/2.2.0/gems/activesupport-4.2.1/lib/active_support/notifications.rb:164:in `block in instrument' 
    # ./.bundle/gems/ruby/2.2.0/gems/activesupport-4.2.1/lib/active_support/notifications/instrumenter.rb:20:in `instrument' 
    # ./.bundle/gems/ruby/2.2.0/gems/activesupport-4.2.1/lib/active_support/notifications.rb:164:in `instrument' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionpack-4.2.1/lib/action_controller/metal/instrumentation.rb:30:in `process_action' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionpack-4.2.1/lib/action_controller/metal/params_wrapper.rb:250:in `process_action' 
    # ./.bundle/gems/ruby/2.2.0/gems/searchkick-0.8.7/lib/searchkick/logging.rb:107:in `process_action' 
    # ./.bundle/gems/ruby/2.2.0/gems/activerecord-4.2.1/lib/active_record/railties/controller_runtime.rb:18:in `process_action' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionpack-4.2.1/lib/abstract_controller/base.rb:137:in `process' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionview-4.2.1/lib/action_view/rendering.rb:30:in `process' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionpack-4.2.1/lib/action_controller/test_case.rb:632:in `process' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionpack-4.2.1/lib/action_controller/test_case.rb:65:in `process' 
    # ./.bundle/gems/ruby/2.2.0/gems/devise-3.4.1/lib/devise/test_helpers.rb:19:in `block in process' 
    # ./.bundle/gems/ruby/2.2.0/gems/devise-3.4.1/lib/devise/test_helpers.rb:72:in `catch' 
    # ./.bundle/gems/ruby/2.2.0/gems/devise-3.4.1/lib/devise/test_helpers.rb:72:in `_catch_warden' 
    # ./.bundle/gems/ruby/2.2.0/gems/devise-3.4.1/lib/devise/test_helpers.rb:19:in `process' 
    # ./.bundle/gems/ruby/2.2.0/gems/actionpack-4.2.1/lib/action_controller/test_case.rb:532:in `delete' 
    # ./spec/controllers/follows_controller_spec.rb:22:in `block (4 levels) in <top (required)>' 
    # ./spec/controllers/follows_controller_spec.rb:22:in `block (3 levels) in <top (required)>' 
    # ./spec/spec_helper.rb:57:in `block (3 levels) in <top (required)>' 
    # ./.bundle/gems/ruby/2.2.0/gems/database_cleaner-1.3.0/lib/database_cleaner/generic/base.rb:15:in `cleaning' 
    # ./.bundle/gems/ruby/2.2.0/gems/database_cleaner-1.3.0/lib/database_cleaner/base.rb:92:in `cleaning' 
    # ./.bundle/gems/ruby/2.2.0/gems/database_cleaner-1.3.0/lib/database_cleaner/configuration.rb:86:in `block (2 levels) in cleaning' 
    # ./.bundle/gems/ruby/2.2.0/gems/database_cleaner-1.3.0/lib/database_cleaner/configuration.rb:87:in `call' 
    # ./.bundle/gems/ruby/2.2.0/gems/database_cleaner-1.3.0/lib/database_cleaner/configuration.rb:87:in `cleaning' 
    # ./spec/spec_helper.rb:56:in `block (2 levels) in <top (required)>' 
+0

你在哪裏定義'delete_request'? –

+0

我錯誤地複製並粘貼了以前的錯誤。上面的修正。 – user2799827

+0

嘗試用'article_id'替換'followable_id' –

回答

0

我覺得路由錯誤確實是因指定followable_id而不是article_id暗示您收到的評論。然而,隨後沒有方法錯誤也是由於在工廠調用中進行了更改。以下是你應該嘗試的:

describe '#DELETE destroy' do 
    it 'deletes a follow' do 
    @article = FactoryGirl.create(:article) 
    follow = FactoryGirl.create(:follow, followable_id: @article.id) 
    # Test if the action really deletes a follow. 
    expect{delete :destroy, id: follow.id, article_id: @article.id}. 
    to change{@article.followers.count}.by(-1) 
    end 
end 
+0

彼得,謝謝你。我已經實現,但現在得到一個錯誤,我認爲這表明我沒有創建一個有效的文章對象:nil:NilClass的未定義方法'stop_following'。 stop_following是由寶石提供的方法。 – user2799827

+0

不,''stop_following'正在'current_user'上被調用,所以你顯然沒有登錄。 –

+0

修復了它。謝謝! – user2799827