在 rspec 中传递表单参数
我正在使用acts_as_audited。在销毁操作的控制器中,我传递了审核注释值。所有这些都运行良好,但是当我尝试测试销毁操作时,我得到:
PurchasesController DELETE /destroy deletes the correct Purchase
Failure/Error: delete :destroy, id: i
NoMethodError:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occured while evaluating nil.[]
# ./app/controllers/purchases_controller.rb:79:in `destroy'
# ./spec/controllers/purchases_controller_spec.rb:156:in `block (3 levels) in <top (required)>'
第 79 行读取:@purchase.audit_comment = params[:purchase][:audit_comment]
这是我的代码:
PurchasesController
def destroy
@purchase = Purchase.find(params[:id])
@purchase.audit_comment = params[:purchase][:audit_comment]
respond_to do |format|
if @purchase.destroy
format.html { redirect_to(purchases_url, notice: "Successfully destroyed purchase.") }
format.xml { render :xml => @purchase, :status => :deleted, :location => @purchase }
else
flash[:alert] = "#{@purchase.po_number} could not be destroyed"
render 'show'
end
end
end
购买 show.html.erb 已编辑
<%= form_for @purchase, method: :delete do |builder| %>
<% if @purchase.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@purchase.errors.count, "error") %> prohibited this purchase from being saved:</h2>
<ul>
<% @purchase.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<% title "Purchase" %>
<div id="delete_button">
<span><strong>PO Number: <%= @purchase.po_number %></strong></span>
<%= render "audit_comment", f: builder %>
<%= builder.submit "Destroy Purchase"%>
</div>
<% end %>
<p>
<%= link_to "Edit", edit_purchase_path(@purchase) %> |
<%= link_to "View All", purchases_path %>
</p>
_audit_comment.html.erb - 购买
<div id = "audit">
<%= f.label :audit_comment %>:<br />
<%= f.text_area :audit_comment, :size => "60x5" %>
</div>
purchase_controller_spec.rb
require 'spec_helper'
require 'ruby-debug'
describe PurchasesController do
login_user
render_views
before(:each) do
@purchase = Factory(:purchase)
end
describe "DELETE /destroy" do
before(:each) do
@ability.can :destroy, Purchase
end
it "deletes the correct Purchase" do
i = @purchase.id
c = Purchase.count
pl = Purchase.find(i).purchase_line_items
cpl = pl.count
delete :destroy, id: i
Purchase.count.should == c-1
pl.count.should == cpl-1
response.should redirect_to(purchases_path)
flash[:notice].should == "Successfully destroyed purchase."
end
it "redirects to the index page with an alert when a delete fails" do
i = @purchase.id
c = Purchase.count
pl = Purchase.find(i).purchase_line_items
cpl = pl.count
Purchase.any_instance.stubs(:valid?).returns(:false)
delete :destroy, id: i
Purchase.count.should_not == c-1
pl.count.should_not == cpl-1
response.should render_template('show')
flash[:alert].should == "#{@purchase.po_number} could not be destroyed"
end
end
end
感谢任何帮助。谢谢!
I am using acts_as_audited. In the controller on the destroy action I pass the audit comment value. All this works well but when I try to test the destroy action I get:
PurchasesController DELETE /destroy deletes the correct Purchase
Failure/Error: delete :destroy, id: i
NoMethodError:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occured while evaluating nil.[]
# ./app/controllers/purchases_controller.rb:79:in `destroy'
# ./spec/controllers/purchases_controller_spec.rb:156:in `block (3 levels) in <top (required)>'
Line #79 reads: @purchase.audit_comment = params[:purchase][:audit_comment]
Heres my code:
PurchasesController
def destroy
@purchase = Purchase.find(params[:id])
@purchase.audit_comment = params[:purchase][:audit_comment]
respond_to do |format|
if @purchase.destroy
format.html { redirect_to(purchases_url, notice: "Successfully destroyed purchase.") }
format.xml { render :xml => @purchase, :status => :deleted, :location => @purchase }
else
flash[:alert] = "#{@purchase.po_number} could not be destroyed"
render 'show'
end
end
end
Purchases show.html.erb EDITED
<%= form_for @purchase, method: :delete do |builder| %>
<% if @purchase.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@purchase.errors.count, "error") %> prohibited this purchase from being saved:</h2>
<ul>
<% @purchase.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<% title "Purchase" %>
<div id="delete_button">
<span><strong>PO Number: <%= @purchase.po_number %></strong></span>
<%= render "audit_comment", f: builder %>
<%= builder.submit "Destroy Purchase"%>
</div>
<% end %>
<p>
<%= link_to "Edit", edit_purchase_path(@purchase) %> |
<%= link_to "View All", purchases_path %>
</p>
_audit_comment.html.erb - Purchases
<div id = "audit">
<%= f.label :audit_comment %>:<br />
<%= f.text_area :audit_comment, :size => "60x5" %>
</div>
purchase_controller_spec.rb
require 'spec_helper'
require 'ruby-debug'
describe PurchasesController do
login_user
render_views
before(:each) do
@purchase = Factory(:purchase)
end
describe "DELETE /destroy" do
before(:each) do
@ability.can :destroy, Purchase
end
it "deletes the correct Purchase" do
i = @purchase.id
c = Purchase.count
pl = Purchase.find(i).purchase_line_items
cpl = pl.count
delete :destroy, id: i
Purchase.count.should == c-1
pl.count.should == cpl-1
response.should redirect_to(purchases_path)
flash[:notice].should == "Successfully destroyed purchase."
end
it "redirects to the index page with an alert when a delete fails" do
i = @purchase.id
c = Purchase.count
pl = Purchase.find(i).purchase_line_items
cpl = pl.count
Purchase.any_instance.stubs(:valid?).returns(:false)
delete :destroy, id: i
Purchase.count.should_not == c-1
pl.count.should_not == cpl-1
response.should render_template('show')
flash[:alert].should == "#{@purchase.po_number} could not be destroyed"
end
end
end
Any help is appreciated. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它告诉您在第 79 行,
params[:purchase]
为 nil。它为零的原因是
button_to
生成自己的表单标记。因此,您现在在编辑问题后更新
HTML 现在看起来不错,但我发现规范存在问题。我认为您忘记将审核注释传递到您的 HTTP 参数中。它位于 HTML 中,但您的规范绕过了表单,因为它单独测试控制器。 (集成测试将使用实际的表单。控制器测试则不会。)因此,您必须手动向请求添加控制器期望的任何表单参数。例如:
It's telling you that at line 79,
params[:purchase]
is nil.The reason it's nil is that
button_to
generates its own form tag. Thus, you now have a<form>
within a<form>
, and your audit comment field is not being submitted. Instead ofbutton_to
, you should usebuilder.submit
. You will also need to set the:method
option in your call toform_for
to make it aDELETE
request.Update after edit to question
The HTML looks OK now, but I see a problem with the spec. I think you're forgetting to pass the audit comment in to your HTTP params. It's there in the HTML, but your spec bypasses the form, because it tests the controller in isolation. (An integration test would use the actual form. Controller tests don't.) Therefore, you'll have to manually add to the request any form params the controller expects. For example: