I've created a small application to demonstrate the problem in more
detail:
http://github.com/cs/nested_attributes_spec_demo
Just clone it, migrate the sqlite database and run `rake spec`. You'll
see 1 failing and 1 succeeding spec. The failing one uses Mocking to
the view. The succeeding example tests exactly the same thing but
actually creates real records in the database (as Matt suggested). I
hope there's a genius somewhere who's able to tell me what I'm doing
wrong or to fix the bug.
Here's the shell script to get it running (for copy and paste):
git clone git://github.com/cs/nested_attributes_spec_demo.git
cd nested_attributes_spec_demo
rake db:migrate
rake db:test:clone
rake spec
On Aug 23, 2009, at 1:57 PM, Matt Wynne wrote:
On 23 Aug 2009, at 10:51, Christoph Schiessl wrote:
I have two models in a has_many relationship. The parent model
(Invoice) accepts the attributes for it's children (InvoiceItem).
The models and the associated controller (InvoicesController) are
absolutely standard stuff. This is the significant part of the model
code:
class Invoice < ActiveRecord::Base
has_many :items, :class_name => "InvoiceItem", :dependent
=> :destroy
accepts_nested_attributes_for :items, :allow_destroy =>
true, :reject_if => Proc.new { |attributes|
attributes['quantity'].blank? &&
attributes['description'].blank? && attributes['unit_price'].blank?
}
validates_presence_of :recipient, :recipient_street
validates_presence_of :recipient_zipcode, :recipient_city
end
class InvoiceItem < ActiveRecord::Base
belongs_to :invoice
validates_presence_of :invoice_id
validates_presence_of :quantity, :description, :unit_price
end
Now, here's part of the view I'm trying to test:
<% form_for @invoice, :html => {:multipart => true} do |f| %>
<p>text fields for recipient, recipient_street, recipient_zipcode,
recipient_city and so on go here</p>
<% f.fields_for :items do |form_item| %>
<p>text fields for quantity, description, unit_price and so on
go here</p>
<% # exception is thrown in the next line: %>
<% unless form_item.object.new_record? %>
<br/><%= form_item.check_box :_delete %>
<%= form_item.label :_delete, "Remove" %>
<% end %>
<% end %>
<% end %>
Everything is working just fine if i test it manually in the browser.
However, I don't get any rspec tests to work.
describe "/invoices/_form.html.erb" do
before do
@items = [mock_model(InvoiceItem), mock_model(InvoiceItem)]
assigns[:invoice] = @invoice = mock_model(Invoice, :items =>
@items)
render
end
it "renders the invoice form" do
response.should have_tag("form")
end
end
When i run `rake spec:views` i get the following error (line
numbers do not match with supplied sample code):
ActionView::TemplateError in '/invoices/_form.html.erb renders the
invoice form'
You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.new_record?
On line #3 of app/views/invoices/_form.html.erb
1: <% form_for @invoice, :html => {:multipart => true} do |f| %>
2: <% f.fields_for :items do |form_item| %>
3: <% unless form_item.object.new_record? %>
4: <br/><%= form_item.check_box :_delete %>
5: <%= form_item.label :_delete, "Remove" %>
6: <% end %>
app/views/invoices/_form.html.erb:3
app/views/invoices/_form.html.erb:2
app/views/invoices/_form.html.erb:1
/spec/views/invoices/_form.html.erb_spec.rb:7
/usr/local/lib/ruby/1.8/timeout.rb:53:in `timeout'
vendor/plugins/rspec/bin/spec:4
So, how do i prevent this? I can't imagine that no one has tried that
before. I appreciate ANY advice or pointers greatly!
I'm just going to make a guess, but I'd say this could be to do with
ActiveRecord's association proxy. I've had a few issues in the past
trying to fake it with an array, as you've done here.
It's ugly, I know, but could you try building a real Invoice
instance in the database (use FactoryGirl, Fixjour or something) and
adding a couple of InvoiceItems to it in your before block? If that
works it would help us to narrow down the problem.
cheers,
Matt
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users