Hi all, I'm having the same problem as Tobi and I wanted to try Tobi mock solution but unfortunately it does not work for me.
Here is a trivial example I want to test: module ActiveRecord class Base def self.count_by_params(params = {}, options = {}) scoped_by_params(params).count end end end And my spec: module ActiveRecord class Base include BaseClassMock end end class DummyUser < ActiveRecord::Base end it "should pass all the params and options to #scope_by_params" do params = { :foo => 1, :bar => 2 } options = { :foo => 3, :bar => 4 } @dummy = DummyUser @dummy.base_class.should_receive(:scope_by_params).with(params, options) DummyUser.count_by_params(params, options) end With the above example and Tobi's BaseClassMock module I'm getting "undefined method `should_receive' for #<Object:0x188c164>". Btw, I also get this when I do not use Tobi be it for for #<Class:0x188cdf8> instead of Object. Any suggestions on what I'm doing wrong or a different approach? Cheers, Jeroen On Sat, Feb 21, 2009 at 10:24 PM, Tobi <listacco...@e-tobi.net> wrote: > Zach Dennis wrote: > > > +1 to composition over inheritance here. Mocking at different layers > > of an inheritance hierarchy sounds like trouble and screams to pull > > that thing apart. > > Good point! I've already tried the composition approach. It solves the > testabilitiy problems, but it doesn't feel right in this case. > > Inheritance seems to be the more natural approach. The C++ application > will call virtual methods on the base class which should be overriden in a > derived class. So it seems to make sense to have the same inheritance tree > in the Ruby counter parts. > > If I would use composition, I would at least need to dynamically extend > the referenced base class so I can override some of the methods that are > the counter parts of the virtual C++ methods. And I would need to expose > the referenced class to the C++ code. > > I've finally found a way to kinda mock the base class in some way: > > module BaseClassMock > attr_accessor :base > > def self.included(klass) > class << klass > @@base_class = Object.new > > def base_class > return @@base_class > end > end > end > > def initialize(*args) > @@base_class.new(*args) if @@base_class.respond_to?(:new) > @base = Object.new > end > > def method_missing(symbol, *args) > @base.send(symbol, *args) > end > end > > Any base class (Swig classes in my case) should then be declared for RSpec > like: > > module Swig > class Base; include BaseClassMock; end > end > > And in the specs I can then do: > > Derived.base_class.should_receive(:new).with('something') > d = Derived.new('something') > > or: > > d = Derived.new > d.base.should_receive(:do_something) > d.do_something > > Tobias > _______________________________________________ > 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