问题描述
使用哪个匹配器,如何测试 @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
解决方案
如何测试这两个?
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)
代码过多。
@ 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 getPosts::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
解决方案
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)
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 fromsave!
you shall to trap withrescue_from
.
这篇关于rspec控制器规范匹配器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!