require 'mocha/expectation'
require 'mocha/metaclass'
module Mocha
# Methods added to mock objects.
# These methods all return an expectation which can be further modified by methods on Mocha::Expectation.
module MockMethods
# :stopdoc:
attr_reader :stub_everything
def expectations
@expectations ||= []
end
# :startdoc:
# :call-seq: expects(method_name) -> expectation
# expects(method_names) -> last expectation
#
# Adds an expectation that a method identified by +method_name+ symbol must be called exactly once with any parameters.
# Returns the new expectation which can be further modified by methods on Mocha::Expectation.
# object = mock()
# object.expects(:method1)
# object.method1
# # no error raised
#
# object = mock()
# object.expects(:method1)
# # error raised, because method1 not called exactly once
# If +method_names+ is a +Hash+, an expectation will be set up for each entry using the key as +method_name+ and value as +return_value+.
# object = mock()
# object.expects(:method1 => :result1, :method2 => :result2)
#
# # exactly equivalent to
#
# object = mock()
# object.expects(:method1).returns(:result1)
# object.expects(:method2).returns(:result2)
def expects(method_names, backtrace = nil)
method_names = method_names.is_a?(Hash) ? method_names : { method_names => nil }
method_names.each do |method_name, return_value|
expectations << Expectation.new(self, method_name, backtrace).returns(return_value)
self.__metaclass__.send(:undef_method, method_name) if self.__metaclass__.method_defined?(method_name)
end
expectations.last
end
alias_method :__expects__, :expects
# :call-seq: stubs(method_name) -> expectation
# stubs(method_names) -> last expectation
#
# Adds an expectation that a method identified by +method_name+ symbol may be called any number of times with any parameters.
# Returns the new expectation which can be further modified by methods on Mocha::Expectation.
# object = mock()
# object.stubs(:method1)
# object.method1
# object.method1
# # no error raised
# If +method_names+ is a +Hash+, an expectation will be set up for each entry using the key as +method_name+ and value as +return_value+.
# object = mock()
# object.stubs(:method1 => :result1, :method2 => :result2)
#
# # exactly equivalent to
#
# object = mock()
# object.stubs(:method1).returns(:result1)
# object.stubs(:method2).returns(:result2)
def stubs(method_names, backtrace = nil)
method_names = method_names.is_a?(Hash) ? method_names : { method_names => nil }
method_names.each do |method_name, return_value|
expectations << Stub.new(self, method_name, backtrace).returns(return_value)
self.__metaclass__.send(:undef_method, method_name) if self.__metaclass__.method_defined?(method_name)
end
expectations.last
end
alias_method :__stubs__, :stubs
# :stopdoc:
def method_missing(symbol, *arguments, &block)
matching_expectation = matching_expectation(symbol, *arguments)
if matching_expectation then
matching_expectation.invoke(&block)
elsif stub_everything then
return
else
begin
super_method_missing(symbol, *arguments, &block)
rescue NoMethodError
unexpected_method_called(symbol, *arguments)
end
end
end
def respond_to?(symbol)
expectations.any? { |expectation| expectation.method_name == symbol }
end
def super_method_missing(symbol, *arguments, &block)
raise NoMethodError
end
def unexpected_method_called(symbol, *arguments)
MissingExpectation.new(self, symbol).with(*arguments).verify
end
def matching_expectation(symbol, *arguments)
expectations.reverse.detect { |expectation| expectation.match?(symbol, *arguments) }
end
def verify(&block)
expectations.each { |expectation| expectation.verify(&block) }
end
# :startdoc:
end
end
syntax highlighted by Code2HTML, v. 0.9.1