Class: MiniTest::Mock
Overview
All mock objects are an instance of Mock
Instance Method Summary collapse
-
#__call(name, data) ⇒ Object
:nodoc:.
- #__respond_to? ⇒ Object
-
#expect(name, retval, args = []) ⇒ Object
Expect that method
name
is called, optionally withargs
, and returnsretval
. -
#initialize ⇒ Mock
constructor
:nodoc:.
-
#method_missing(sym, *args) ⇒ Object
:nodoc:.
-
#respond_to?(sym, include_private = false) ⇒ Boolean
:nodoc:.
-
#verify ⇒ Object
Verify that all methods were called as expected.
Constructor Details
#initialize ⇒ Mock
:nodoc:
21 22 23 24 |
# File 'lib/minitest/mock.rb', line 21 def initialize # :nodoc: @expected_calls = Hash.new { |calls, name| calls[name] = [] } @actual_calls = Hash.new { |calls, name| calls[name] = [] } end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *args) ⇒ Object
:nodoc:
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/minitest/mock.rb', line 85 def method_missing(sym, *args) # :nodoc: unless @expected_calls.has_key?(sym) then raise NoMethodError, "unmocked method %p, expected one of %p" % [sym, @expected_calls.keys.sort_by(&:to_s)] end index = @actual_calls[sym].length expected_call = @expected_calls[sym][index] unless expected_call then raise MockExpectationError, "No more expects available for %p: %p" % [sym, args] end expected_args, retval = expected_call[:args], expected_call[:retval] if expected_args.size != args.size then raise ArgumentError, "mocked method %p expects %d arguments, got %d" % [sym, expected_args.size, args.size] end fully_matched = expected_args.zip(args).all? { |mod, a| mod === a or mod == a } unless fully_matched then raise MockExpectationError, "mocked method %p called with unexpected arguments %p" % [sym, args] end @actual_calls[sym] << { :retval => retval, :args => expected_args.zip(args).map { |mod, a| mod === a ? mod : a } } retval end |
Instance Method Details
#__call(name, data) ⇒ Object
:nodoc:
53 54 55 56 57 58 59 60 |
# File 'lib/minitest/mock.rb', line 53 def __call name, data # :nodoc: case data when Hash then "#{name}(#{data[:args].inspect[1..-2]}) => #{data[:retval].inspect}" else data.map { |d| __call name, d }.join ", " end end |
#__respond_to? ⇒ Object
13 |
# File 'lib/minitest/mock.rb', line 13 alias :__respond_to? :respond_to? |
#expect(name, retval, args = []) ⇒ Object
Expect that method name
is called, optionally with args
, and returns retval
.
@mock.expect(:meaning_of_life, 42)
@mock.meaning_of_life # => 42
@mock.expect(:do_something_with, true, [some_obj, true])
@mock.do_something_with(some_obj, true) # => true
args
is compared to the expected args using case equality (ie, the ‘===’ operator), allowing for less specific expectations.
@mock.expect(:uses_any_string, true, [String])
@mock.uses_any_string("foo") # => true
@mock.verify # => true
@mock.expect(:uses_one_string, true, ["foo"]
@mock.uses_one_string("bar") # => true
@mock.verify # => raises MockExpectationError
47 48 49 50 51 |
# File 'lib/minitest/mock.rb', line 47 def expect(name, retval, args=[]) raise ArgumentError, "args must be an array" unless Array === args @expected_calls[name] << { :retval => retval, :args => args } self end |
#respond_to?(sym, include_private = false) ⇒ Boolean
:nodoc:
123 124 125 126 |
# File 'lib/minitest/mock.rb', line 123 def respond_to?(sym, include_private = false) # :nodoc: return true if @expected_calls.has_key?(sym.to_sym) return __respond_to?(sym, include_private) end |
#verify ⇒ Object
Verify that all methods were called as expected. Raises MockExpectationError
if the mock object was not called as expected.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/minitest/mock.rb', line 67 def verify @expected_calls.each do |name, calls| calls.each do |expected| msg1 = "expected #{__call name, expected}" msg2 = "#{msg1}, got [#{__call name, @actual_calls[name]}]" raise MockExpectationError, msg2 if @actual_calls.has_key?(name) and not @actual_calls[name].include?(expected) raise MockExpectationError, msg1 unless @actual_calls.has_key?(name) and @actual_calls[name].include?(expected) end end true end |