[rspec-users] Mocking base class methods

Tobi listaccount at e-tobi.net
Sat Feb 21 16:24:06 EST 2009


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


More information about the rspec-users mailing list