Rspec:测试嵌套销毁操作

shr*_*roy 1 ruby rspec ruby-on-rails factory-bot

我正在尝试测试嵌套注释控制器的“销毁”操作。Post has_many Comments。我之前遇到过类似的问题,并且知道我需要传递一个 id,但我仍然遇到一个非常熟悉的错误......

\n\n
Failures:\n\n  1) CommentsController#DELETE destroy deletes a comment\n     Failure/Error: delete :destroy, comment: create(:comment), post_id: @post\n     ActionController::UrlGenerationError:\n       No route matches {:action=>"destroy", :comment=>"1", :controller=>"comments", :post_id=>"1"}\n     # ./spec/controllers/comments_controller_spec.rb:19:in `block (3 levels) in <top (required)>\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

评论控制器规范.rb

\n\n
RSpec.describe CommentsController, :type => :controller do\n        before :each do\n          @post = FactoryGirl.create(:post)\n        end\n\n\n    ....\n\n\n        describe \'#DELETE destroy\' do\n          it \'deletes a comment\' do\n            delete :destroy, comment: create(:comment), post_id: @post\n            expect(response).to redirect_to post_path\n          end\n        end\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

评论控制器.rb

\n\n
def destroy\n    @post = Post.find(params[:post_id])\n    @comment = @post.comments.find(params[:id])\n\n    @comment.destroy\n    redirect_to post_path(@post)\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

路线.rb

\n\n
 resources :posts do\n  resources :comments\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

耙路线

\n\n
\xe2\x98\xb9 rake routes\n           Prefix Verb   URI Pattern                                 Controller#Action\n             root GET    /                                           posts#index\n    post_comments GET    /posts/:post_id/comments(.:format)          comments#index\n                  POST   /posts/:post_id/comments(.:format)          comments#create\n new_post_comment GET    /posts/:post_id/comments/new(.:format)      comments#new\nedit_post_comment GET    /posts/:post_id/comments/:id/edit(.:format) comments#edit\n     post_comment GET    /posts/:post_id/comments/:id(.:format)      comments#show\n                  PATCH  /posts/:post_id/comments/:id(.:format)      comments#update\n                  PUT    /posts/:post_id/comments/:id(.:format)      comments#update\n                  DELETE /posts/:post_id/comments/:id(.:format)      comments#destroy\n            posts GET    /posts(.:format)                            posts#index\n                  POST   /posts(.:format)                            posts#create\n         new_post GET    /posts/new(.:format)                        posts#new\n        edit_post GET    /posts/:id/edit(.:format)                   posts#edit\n             post GET    /posts/:id(.:format)                        posts#show\n                  PATCH  /posts/:id(.:format)                        posts#update\n                  PUT    /posts/:id(.:format)                        posts#update\n                  DELETE /posts/:id(.:format)                        posts#destroy\n
Run Code Online (Sandbox Code Playgroud)\n

hat*_*enn 5

您要请求的路线是这样的:

/posts/:post_id/comments/:id(.:format)

但您要发送以下参数:

{:action=>"destroy", :comment=>"1", :controller=>"comments", :post_id=>"1"}

您需要将comment.id作为id参数发送。

尝试这个:

describe '#DELETE destroy' do
  it 'deletes a comment' do
    comment = create(:comment)
    @post.comments << comment
    # Also, test if the action really deletes a comment.
    expect{delete :destroy, id: comment.id, post_id: @post}.
    to change{@post.comments.count}.by(-1)
    expect(response).to redirect_to post_path
  end
end
Run Code Online (Sandbox Code Playgroud)