[rspec-devel] [ rspec-Feature Requests-6980 ] Can't set expectations on Rails association proxy object

noreply at rubyforge.org noreply at rubyforge.org
Fri May 4 02:36:09 EDT 2007


Feature Requests item #6980, was opened at 2006-11-29 22:34
You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=3152&aid=6980&group_id=797

Category: rails plugin
Group: None
>Status: Closed
Priority: 1
Submitted By: Pat Maddox (pergesu)
Assigned to: Nobody (None)
Summary: Can't set expectations on Rails association proxy object

Initial Comment:
edge rails, 0.7.3

context "Given a call to destroy, a Person" do
  setup do
    @person = Person.create :name => "Me", :user_id => 1
    @person.add_item Item.new(:name => "Item")
  end

  specify "should destroy its items" do
    @person.items.should_receive(:delete_all)
    @person.destroy
  end
end

This assumes the following config in Person.rb
has_many :items, :dependent => :delete_all

The failure is:
NoMethodError in 'Given a call to destroy, a Person should destroy its items'
undefined method `receive?' for Item:Class

My best guess is that since items is a proxy class defined at runtime, the should_receive method isn't getting mixed into it.

----------------------------------------------------------------------

Comment By: David Chelimsky (dchelimsky)
Date: 2006-11-30 20:58

Message:
handle_underscores_for_rspec! doesn't reinstate the should methods - it reinstates the underscore sugar that gets invoked on method_missing. Right now, that is only still in existence to support should_be_predicate, but that is on its way out soon.

I added the following to 
puts ActiveRecord::Associations::HasManyAssociation.included_modules.inspect
ActiveRecord::Associations::HasManyAssociation.send :include, Spec::Mocks::MockMethods
puts ActiveRecord::Associations::HasManyAssociation.included_modules.inspect

Here's what it output:

[Base64::Deprecated, Base64, Spec::Mocks::MockMethods, Spec::Expectations::UnderscoreSugar, Spec::Expectations::ObjectExpectations, Callback::InstanceMethods, Kernel]
[Base64::Deprecated, Base64, Spec::Mocks::MockMethods, Spec::Expectations::UnderscoreSugar, Spec::Expectations::ObjectExpectations, Callback::InstanceMethods, Kernel]

Note that Spec::Mock::MockMethods appears before and after. So there's something happening at runtime.

----------------------------------------------------------------------

Comment By: Wilson Bilkovich (wilson)
Date: 2006-11-30 20:28

Message:
"add_underscores_for_rspec!" gets called on the association base class after that code is parsed, though, and overrides it.

That shouldn't be the problem.

----------------------------------------------------------------------

Comment By: David Chelimsky (dchelimsky)
Date: 2006-11-30 19:43

Message:
Ugh!

In activerecord/lib/active_record/associations/association_proxy.rb:

class AssociationProxy #:nodoc:
  attr_reader :reflection
  alias_method :proxy_respond_to?, :respond_to?
  alias_method :proxy_extend, :extend
  instance_methods.each { |m| undef_method m unless m =~  /(^__|^nil\?|^proxy_respond_to\?|^proxy_extend|^send)/ }

That last line removes all of the rspec methods. Even if I add ^should_ to the list of methods NOT to undef, I get an error saying that items won't respond_to :delete_all.

So Rails is doing a bunch of magic to get things to behave in a way that is somewhat different from how they LOOK like they behave.

I'd recommend checking the collection size before and after using should_change for now:

lambda { @person.destroy }.should_change(Item, :count).by(-1)

It is state-based, but at least you can DO it, and I'd rather focus our energies on getting the rails plugin to do things you can not do at all for the time being.

David


----------------------------------------------------------------------

Comment By: David Chelimsky (dchelimsky)
Date: 2006-11-30 16:41

Message:
Have you tried this against 1.1.6? Just curious.

----------------------------------------------------------------------

You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=3152&aid=6980&group_id=797


More information about the rspec-devel mailing list