# = mock.rb # # == Copyright (c) 2005 George Moschovitis # # Ruby License # # This module is free software. You may use, modify, and/or redistribute this # software under the same terms as Ruby. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. # # == Author(s) # # * George Moschovitis require 'ostruct' module Quarry # Factory method for creating semi-functional mock object classes given the # class which is to be mocked. It looks like a constant for purposes # of syntactic sugar. def Mockery( realclass ) mockclass = Class.new( Mock ) mockclass.instance_eval do @mocked_class = realclass end # Provide an accessor to class instance var that holds the class # object we're faking class << mockclass # The actual class being mocked attr_reader :mocked_class # Propagate the mocked class ivar to derivatives so it can be # called like: # class MockFoo < Mock( RealClass ) def inherited( subclass ) mc = self.mockedClass subclass.instance_eval do @mocked_class = mc end end end # Build method definitions for all the mocked class's instance # methods, as well as those given to it by its superclasses, since # we're not really inheriting from it. imethods = realclass.instance_methods(true).collect do |name| next if name =~ ::Mock::UnmockedMethods # Figure out the argument list arity = realclass.instance_method( name ).arity optargs = false if arity < 0 optargs = true arity = (arity+1).abs end args = [] arity.times do |n| args << "arg#{n+1}" end args << "*optargs" if optargs # Build a method definition. Some methods need special # declarations. argsj = args.join(',') case name.intern when :initialize "def initialize(#{argsj}) ; super ; end" else "def #{name}(#{argsj}) ; self.send(#{name},#{argsj}) ; end" #"def %s( %s ) ; self.__mockRegisterCall(%s) ; end" % # [ name, argstr, [":#{name}", *args].join(',') ] end end # Now add the instance methods to the mockclass class mockclass.class_eval imethods.join( "\n" ) return mockclass end end