【问题标题】:Rspec: Testing nested destroy actionRspec:测试嵌套的销毁动作
【发布时间】:2015-03-16 21:12:39
【问题描述】:

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

Failures:

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

cmets_controller_spec.rb

RSpec.describe CommentsController, :type => :controller do
        before :each do
          @post = FactoryGirl.create(:post)
        end


    ....


        describe '#DELETE destroy' do
          it 'deletes a comment' do
            delete :destroy, comment: create(:comment), post_id: @post
            expect(response).to redirect_to post_path
          end
        end
end

cmets_controller.rb

def destroy
    @post = Post.find(params[:post_id])
    @comment = @post.comments.find(params[:id])

    @comment.destroy
    redirect_to post_path(@post)
end

routes.rb

 resources :posts do
  resources :comments
end

耙路

☹ rake routes
           Prefix Verb   URI Pattern                                 Controller#Action
             root GET    /                                           posts#index
    post_comments GET    /posts/:post_id/comments(.:format)          comments#index
                  POST   /posts/:post_id/comments(.:format)          comments#create
 new_post_comment GET    /posts/:post_id/comments/new(.:format)      comments#new
edit_post_comment GET    /posts/:post_id/comments/:id/edit(.:format) comments#edit
     post_comment GET    /posts/:post_id/comments/:id(.:format)      comments#show
                  PATCH  /posts/:post_id/comments/:id(.:format)      comments#update
                  PUT    /posts/:post_id/comments/:id(.:format)      comments#update
                  DELETE /posts/:post_id/comments/:id(.:format)      comments#destroy
            posts GET    /posts(.:format)                            posts#index
                  POST   /posts(.:format)                            posts#create
         new_post GET    /posts/new(.:format)                        posts#new
        edit_post GET    /posts/:id/edit(.:format)                   posts#edit
             post GET    /posts/:id(.:format)                        posts#show
                  PATCH  /posts/:id(.:format)                        posts#update
                  PUT    /posts/:id(.:format)                        posts#update
                  DELETE /posts/:id(.:format)                        posts#destroy

【问题讨论】:

  • 能否请您发布您的相关routes.rb 并从rake routes 输出
  • @patrick - 编辑帖子以包含这些文件。

标签: ruby-on-rails ruby rspec factory-bot


【解决方案1】:

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

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

但是您发送的是以下参数:

{:action=&gt;"destroy", :comment=&gt;"1", :controller=&gt;"comments", :post_id=&gt;"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

【讨论】:

  • 刚刚看到编辑,但额外的测试以查看操作是否真的是删除评论不起作用。 ArgumentError: change` 需要对象和消息 (change(obj, :msg)) 或块 (change { })。你传递了一个对象但没有消息。`
  • 我将参数改为块{ @post.comments },但仍然收到错误:expected result to have changed by -1, but was changed by []
  • @Shroy 评论在第一次请求时被缓存。您需要重新加载 cmets 关联并获取其大小:{ @post.comments.reload.size }。你也可以使用count,它总是能到达数据库:{ @post.comments.count }
  • @Shroy,抱歉,代码没有经过测试。我现在改了,应该可以了。正如@cbliard 所说,正确的方法是检查@post.comment.count 的差异。
  • @cbliard hattenn - 谢谢,这绝对有效,也很有意义!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-01
  • 1970-01-01
相关资源
最近更新 更多