I have just the same problem. Any suggestion? TIA, Yury
Christoph Schiessl wrote: > 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 >> [email protected] >> http://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > rspec-users mailing list > [email protected] > http://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ rspec-users mailing list [email protected] http://rubyforge.org/mailman/listinfo/rspec-users
