An abstract base class that provides the setup and testing methods to concrete mock objects.
class | -> | __class |
Handle type and class methods | ||
class | -> | type |
kind_of? | -> | is_a? |
Instantiate and return a new mock object after recording the specified args.
# File mock.rb, line 120 def initialize( *args ) @args = args @calls = [] @activated = nil @returnValues = Hash::new( true ) @callOrder = [] @strictCallOrder = false end
Turn on call registration — begin testing.
# File mock.rb, line 265 def activate raise "Already activated!" if @activated self.__clear @activated = Time::now end
Returns an array of Strings describing, in cronological order, what method calls were registered with the object.
# File mock.rb, line 230 def callTrace return [] unless @activated @calls.collect {|call| "%s( %s ) at %0.5f seconds from %s" % [ call[:method].to_s, call[:args].collect {|arg| arg.inspect}.join(","), call[:time] - @activated, call[:caller][0] ] } end
Deactivate the object without doing call order checks and clear the call list, but keep its configuration.
# File mock.rb, line 311 def clear @calls.clear @activated = nil end
Returns an array of Strings describing, in cronological order, what method calls were registered with the object along with a full stacktrace for each call.
# File mock.rb, line 248 def fullCallTrace return [] unless @activated @calls.collect {|call| "%s( %s ) at %0.5f seconds. Called from %s\n\t%s" % [ call[:method].to_s, call[:args].collect {|arg| arg.inspect}.join(","), call[:time] - @activated, call[:caller][0], call[:caller][1..-1].join("\n\t"), ] } end
Clear the call list and call order, unset any return values, and deactivate the object without checking for conformance to the call order.
# File mock.rb, line 321 def reset self.__clear @callOrder.clear @returnValues.clear end
Set the return value for one or more methods. The hash should contain one or more key/value pairs, the key of which is the symbol which corresponds to the method being configured, and the value which is a specification of the value to be returned. More complex returns can be configured with one the following types of values:
Any other value will be returned as-is. To return one of the above types of objects literally, just wrap it in an Array like so:
# Return a literal Proc without calling it: mockObj.setReturnValues( :meth => [myProc] ) # Return a literal Array: mockObj.setReturnValues( :meth => [["an", "array", "of", "stuff"]] )
# File mock.rb, line 184 def setReturnValues( hash ) @returnValues.update hash end
Set the strict call order flag. When verify is called, the methods specified in calls to setCallOrder will be checked against the actual methods that were called on the object. If this flag is set to true, any deviation (missing, misordered, or extra calls) results in a failed assertion. If it is not set, other method calls may be interspersed between the calls specified without effect, but a missing or misordered method still fails.
# File mock.rb, line 209 def strictCallOrder=( flag ) @strictCallOrder = true if flag end
Returns true if strict call order checking is enabled.
# File mock.rb, line 217 def strictCallOrder? @strictCallOrder end
Verify the registered required methods were called with the specified args
# File mock.rb, line 275 def verify raise "Cannot verify a mock object that has never been "\ "activated." unless @activated return true if @callOrder.empty? actualCallOrder = @calls.collect {|call| call[:method]} diff = Diff::diff( @callOrder, actualCallOrder ) # In strict mode, any differences are failures if @strictCallOrder msg = "{Message}" assert_block( msg ) { unless diff.empty? msg.replace __makeCallOrderFailMsg(*diff[0]) end diff.empty? } # In non-strict mode, only methods missing (:-) from the call # order are failures. else msg = "{Message}" assert_block( msg ) { missingDiff = diff.find {|d| d[0] == :-} unless missingDiff.nil? msg.replace __makeCallOrderFailMsg( *missingDiff ) end missingDiff.nil? } end end
Build and return an error message for a call-order verification failure. The expected arguments are those returned in an element of the Array that is returned from Diff::diff.
# File mock.rb, line 374 def __makeCallOrderFailMsg( action, position, elements ) case action # "Extra" method/s when :+ extraCall = @calls[ position ] return "Call order assertion failed: Unexpected method %s "\ "called from %s at %0.5f" % [ extraCall[:method].inspect, extraCall[:caller][0], extraCall[:time] - @activated ] when :- # If there is a call in the position specified, it was a # misordered or extra call. If not, there was a missing # call. missingCall = @callOrder[ position ] if extraCall = @calls[ position ] return "Call order assertion failed: Expected call to %s, "\ "but got call to %s from %s at %0.5f instead" % [ missingCall.inspect, extraCall[:method].inspect, extraCall[:caller][0], extraCall[:time] - @activated ] else return "Call order assertion failed: Missing call to %s." % missingCall.inspect end else return "Unknown diff action '#{action.inspect}'" end end
Register a call to the faked method designated by sym if the object is activated, and return a value as configured by setReturnValues given the specified args.
# File mock.rb, line 336 def __mockRegisterCall( sym, *args, &block ) if @activated @calls.push({ :method => sym, :args => args, :time => Time::now, :caller => caller(2), }) end rval = @returnValues[ sym ] case rval when Method, Proc thisrval = rval.call( *args, &block ) when Array thisrval = rval.push( rval.shift )[-1] when Hash thisrval = rval[ args ] else thisrval = rval end if thisrval.is_a?( Exception ) Kernel::raise( thisrval, thisrval.message, caller(1) ) end return thisrval end