rspec控制器规范匹配器 [英] rspec controller spec matchers

查看:280
本文介绍了rspec控制器规范匹配器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用哪个匹配器,如何测试 @post_comment @ post_comment.user 是否正确分配?



expect(assigns(:post_comment))。to be_a_new(PostComment) >

更新:



使用以下设置我也得到以下错误。

 帖子:: PostCommentsController当用户登录时POST创建无效的属性不会将新产品保存在db 
中失败/错误:@ post_comment.save!

ActiveRecord :: RecordInvalid:
验证失败:正文不能为空

如果我删除 @ post_comment.save!,那么我会得到

  Posts :: PostCommentsController当用户登录时POST使用无效属性创建不会在db 
中保存新产品失败/错误:< span class =post-comment-updated> ;%= local_time_ago(post_comment.updated_at)%>< / span>

ActionView :: Template ::错误:
未定义的方法`to_time'for nil:NilClass

post_comments_controller

  def create 
@post = Post.find(params [:post_id ])
@post_comment = @ post.post_comments.build(post_comment_params)
授权@post_comment
@ post_comment.user = current_user
@ post_comment.save!
if @ post_comment.save
@ post.send_post_comment_creation_notification(@post_comment)
@post_comment_reply = PostCommentReply.new
respond_to do | format |
format.html {redirect_to posts_path,notice:评论已保存! }
format.js
end
end
end

post_comments_controller_spec.rb

  describePOST createdo 
let!(:profile){create ,user:@user)}
let!(:post_instance){create(:post,user:@user)}

上下文有效属性do
subject :create_action){xhr:post,:create,post_id:post_instance.id,post_comment:attributes_for(:post_comment,post_id:post_instance.id,user:@user)}

it保存新任务在dbdo
expect {create_action} .to change {PostComment.count} .by(1)
end

它分配实例变量do
create_action
expect(assigns(:post))。to eq(post_instance)
#########如何测试这两个?
#expect(assigns(:post_comment))。to be_a_new(PostComment)
#expect(assigns(:post_comment.user))to eq(@user)
expect(assigns post_comment_reply))to be_a_new(PostCommentReply)
end

它分配所有的实例变量

它成功响应do
create_action
expect(response).to have_http_status(200)
end
end

上下文具有无效属性do
subject(:create_action){xhr :post,:create,post_id:post_instance.id,post_comment:attributes_for(:post_comment,post_id:post_instance.id,user:@user,body:)}

it新产品在dbdo
expect {create_action} .to_not change {PostComment.count}
end
end
end


解决方案


  1. 如何测试这两个?

      expect(assigns(:post_comment))to be_a_new(PostComment)
    expect(assigns(:post_comment.user))。 @user)



    我相信你不是一个新记录,而是一个类的记录,持久化记录:

      expect(assigns(:post_comment))to be_a(PostComment)
    expect post_comment))to be_presisted
    expect(assigns(:post_comment.user))。to eq(@user)


  2. 代码过多。

      @ post_comment.save! 
    if @ post_comment.save

    您应该只保留那个记录,相信这是足够的例外:

      @ post_comment.save! 

    所以其他部分代码可以选择 if 块。 豁免 save!您将陷入 rescue_from



With which matcher and how can I test if the @post_comment and @post_comment.user is properly assigned?

expect(assigns(:post_comment)).to be_a_new(PostComment) is not working here.

UPDATE:

With the following setup I also get the following error. What should I change to be able to test the invalid attrs?

Posts::PostCommentsController when user is logged in POST create with invalid attributes doesn't save the new product in the db
 Failure/Error: @post_comment.save!

 ActiveRecord::RecordInvalid:
   Validation failed: Body can't be blank

IF I delete @post_comment.save! then I get

Posts::PostCommentsController when user is logged in POST create with invalid attributes doesn't save the new product in the db
 Failure/Error: <span class="post-comment-updated"><%= local_time_ago(post_comment.updated_at) %></span>

 ActionView::Template::Error:
   undefined method `to_time' for nil:NilClass

post_comments_controller

  def create
    @post = Post.find(params[:post_id])
    @post_comment = @post.post_comments.build(post_comment_params)
    authorize @post_comment
    @post_comment.user = current_user
    @post_comment.save!
    if @post_comment.save
      @post.send_post_comment_creation_notification(@post_comment)
      @post_comment_reply = PostCommentReply.new
      respond_to do |format|
        format.html { redirect_to posts_path, notice: "Comment saved!" }
        format.js
      end
    end
  end

post_comments_controller_spec.rb

describe "POST create" do
  let!(:profile) { create(:profile, user: @user) }
  let!(:post_instance) { create(:post, user: @user) } 

  context "with valid attributes" do
    subject(:create_action) { xhr :post, :create, post_id: post_instance.id, post_comment: attributes_for(:post_comment, post_id: post_instance.id, user: @user) }

    it "saves the new task in the db" do
      expect{ create_action }.to change{ PostComment.count }.by(1)
    end

    it "assigns instance variables" do
      create_action
      expect(assigns(:post)).to eq(post_instance)
      #########How to test these two?
      #expect(assigns(:post_comment)).to be_a_new(PostComment)
      #expect(assigns(:post_comment.user)).to eq(@user)
      expect(assigns(:post_comment_reply)).to be_a_new(PostCommentReply)
    end

    it "assigns all the instance variables"

    it "responds with success" do
      create_action
      expect(response).to have_http_status(200)
    end
  end

  context "with invalid attributes" do
    subject(:create_action) { xhr :post, :create, post_id: post_instance.id, post_comment: attributes_for(:post_comment, post_id: post_instance.id, user: @user, body: "") }

    it "doesn't save the new product in the db" do
      expect{ create_action }.to_not change{ PostComment.count }
    end
  end
end

解决方案

  1. How to test these two?

    expect(assigns(:post_comment)).to be_a_new(PostComment)
    expect(assigns(:post_comment.user)).to eq(@user)
    

    I believe you shoudl test not a new record, but a record of a class, and persisted record:

    expect(assigns(:post_comment)).to be_a(PostComment)
    expect(assigns(:post_comment)).to be_presisted
    expect(assigns(:post_comment.user)).to eq(@user)
    

  2. Excessive code.

    @post_comment.save!
    if @post_comment.save
    

    You shall to keep only the single record of that, I believe it is enough save with exception:

    @post_comment.save! 
    

    So other part code you can pick out of if block. Exception from save! you shall to trap with rescue_from.

这篇关于rspec控制器规范匹配器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆