class RSpec::Mocks::MessageExpectation
def actual_received_count_matters?
- Private: -
def actual_received_count_matters? @at_least || @at_most || @exactly end
def advise(*args)
- Private: -
def advise(*args) similar_messages << args end
def and_call_original
- Note: - This is only available on partial mock objects.
def and_call_original if RSpec::Mocks::TestDouble === @method_double.object @error_generator.raise_only_valid_on_a_partial_mock(:and_call_original) else if implementation.inner_action RSpec.warning("You're overriding a previous implementation for this stub") end @implementation = AndCallOriginalImplementation.new(@method_double.original_method) @yield_receiver_to_implementation_block = false end end
def and_raise(exception = RuntimeError, message = nil)
- Note: -
Overloads:
-
and_raise(exception_instance)
-
and_raise(ExceptionClass, message)
-
and_raise(ExceptionClass)
-
and_raise
def and_raise(exception = RuntimeError, message = nil) if exception.respond_to?(:exception) exception = message ? exception.exception(message) : exception.exception end self.terminal_implementation_action = Proc.new { raise exception } nil end
def and_return(*values, &implementation)
-
and_return(&block)
-
and_return(first_value, second_value)
-
and_return(value)
def and_return(*values, &implementation) if negative? raise "`and_return` is not supported with negative message expectations" else @expected_received_count = [@expected_received_count, values.size].max unless ignoring_args? || (@expected_received_count == 0 and @at_least) if implementation # TODO: deprecate `and_return { value }` self.inner_implementation_action = implementation else self.terminal_implementation_action = AndReturnImplementation.new(values) end nil end end
def and_throw(*args)
-
and_throw(symbol, object)
-
and_throw(symbol)
def and_throw(*args) self.terminal_implementation_action = Proc.new { throw(*args) } nil end
def and_yield(*args, &block)
@example
is received.
Tells the object to yield one or more args to a block when the message
def and_yield(*args, &block) yield @eval_context = Object.new if block @args_to_yield << args self.initial_implementation_action = AndYieldImplementation.new(@args_to_yield, @eval_context, @error_generator) self end
def and_yield_receiver_to_implementation
def and_yield_receiver_to_implementation @yield_receiver_to_implementation_block = true self end
def at_least(n, &block)
@example
number of times.
Constrain a message expectation to be received at least a specific
def at_least(n, &block) set_expected_received_count :at_least, n if n == 0 raise "at_least(0) has been removed, use allow(...).to receive(:message) instead" end self.inner_implementation_action = block self end
def at_most(n, &block)
@example
number of times.
Constrain a message expectation to be received at most a specific
def at_most(n, &block) self.inner_implementation_action = block set_expected_received_count :at_most, n self end
def called_max_times?
- Private: -
def called_max_times? @expected_received_count != :any && !@at_least && @expected_received_count > 0 && @actual_received_count >= @expected_received_count end
def description
- Private: -
def description @error_generator.describe_expectation(@message, @expected_received_count, @actual_received_count, *expected_args) end
def ensure_expected_ordering_received!
def ensure_expected_ordering_received! @order_group.verify_invocation_order(self) if @ordered true end
def exactly(n, &block)
@example
times.
Constrain a message expectation to be received a specific number of
def exactly(n, &block) self.inner_implementation_action = block set_expected_received_count :exactly, n self end
def expectation_count_type
def expectation_count_type return :at_least if @at_least return :at_most if @at_most return nil end
def expected_args
- Private: -
def expected_args @argument_list_matcher.expected_args end
def expected_messages_received?
- Private: -
def expected_messages_received? ignoring_args? || matches_exact_count? || matches_at_least_count? || matches_at_most_count? end
def failed_fast?
def failed_fast? @failed_fast end
def generate_error
- Private: -
def generate_error if similar_messages.empty? @error_generator.raise_expectation_error(@message, @expected_received_count, @argument_list_matcher, @actual_received_count, expectation_count_type, *expected_args) else @error_generator.raise_similar_message_args_error(self, *@similar_messages) end end
def ignoring_args?
- Private: -
def ignoring_args? @expected_received_count == :any end
def increase_actual_received_count!
- Private: -
def increase_actual_received_count! @actual_received_count += 1 end
def initial_implementation_action=(action)
def initial_implementation_action=(action) implementation.initial_action = action end
def initialize(error_generator, expectation_ordering, expected_from, method_double,
- Private: -
def initialize(error_generator, expectation_ordering, expected_from, method_double, expected_received_count=1, opts={}, &implementation_block) @error_generator = error_generator @error_generator.opts = opts @expected_from = expected_from @method_double = method_double @orig_object = @method_double.object @message = @method_double.method_name @actual_received_count = 0 @expected_received_count = expected_received_count @argument_list_matcher = ArgumentListMatcher::MATCH_ALL @order_group = expectation_ordering @order_group.register(self) @ordered = false @at_least = @at_most = @exactly = nil @args_to_yield = [] @failed_fast = nil @eval_context = nil @yield_receiver_to_implementation_block = false @implementation = Implementation.new self.inner_implementation_action = implementation_block end
def inner_implementation_action=(action)
def inner_implementation_action=(action) RSpec.warning("You're overriding a previous implementation for this stub") if implementation.inner_action implementation.inner_action = action if action end
def invoke(parent_stub, *args, &block)
- Private: -
def invoke(parent_stub, *args, &block) if yield_receiver_to_implementation_block? args.unshift(orig_object) end if negative? || ((@exactly || @at_most) && (@actual_received_count == @expected_received_count)) @actual_received_count += 1 @failed_fast = true #args are the args we actually received, @argument_list_matcher is the #list of args we were expecting @error_generator.raise_expectation_error(@message, @expected_received_count, @argument_list_matcher, @actual_received_count, expectation_count_type, *args) end @order_group.handle_order_constraint self begin if implementation.present? implementation.call(*args, &block) elsif parent_stub parent_stub.invoke(nil, *args, &block) end ensure @actual_received_count += 1 end end
def matches?(message, *args)
- Private: -
def matches?(message, *args) @message == message && @argument_list_matcher.args_match?(*args) end
def matches_at_least_count?
- Private: -
def matches_at_least_count? @at_least && @actual_received_count >= @expected_received_count end
def matches_at_most_count?
- Private: -
def matches_at_most_count? @at_most && @actual_received_count <= @expected_received_count end
def matches_exact_count?
- Private: -
def matches_exact_count? @expected_received_count == @actual_received_count end
def matches_name_but_not_args(message, *args)
- Private: -
def matches_name_but_not_args(message, *args) @message == message and not @argument_list_matcher.args_match?(*args) end
def negative?
- Private: -
def negative? @expected_received_count == 0 && !@at_least end
def negative_expectation_for?(message)
- Private: -
def negative_expectation_for?(message) @message == message && negative? end
def never
@example
Expect a message not to be received at all.
def never ErrorGenerator.raise_double_negation_error("expect(obj)") if negative? @expected_received_count = 0 self end
def once(&block)
@example
Expect a message to be received exactly one time.
def once(&block) self.inner_implementation_action = block set_expected_received_count :exactly, 1 self end
def ordered(&block)
api.should_receive(:run).ordered
api.should_receive(:prepare).ordered
@example
Expect messages to be received in a specific order.
def ordered(&block) self.inner_implementation_action = block @ordered = true self end
def ordered?
- Private: -
def ordered? @ordered end
def raise_out_of_order_error
def raise_out_of_order_error @error_generator.raise_out_of_order_error @message end
def set_expected_received_count(relativity, n)
def set_expected_received_count(relativity, n) @at_least = (relativity == :at_least) @at_most = (relativity == :at_most) @exactly = (relativity == :exactly) @expected_received_count = case n when Numeric then n when :once then 1 when :twice then 2 end end
def similar_messages
- Private: -
def similar_messages @similar_messages ||= [] end
def terminal_implementation_action=(action)
def terminal_implementation_action=(action) implementation.terminal_action = action end
def times(&block)
dealer.should_receive(:deal_card).at_least(10).times
dealer.should_receive(:deal_card).exactly(10).times
@example
Syntactic sugar for `exactly`, `at_least` and `at_most`
def times(&block) self.inner_implementation_action = block self end
def twice(&block)
@example
Expect a message to be received exactly two times.
def twice(&block) self.inner_implementation_action = block set_expected_received_count :exactly, 2 self end
def verify_messages_received
- Private: -
def verify_messages_received InsertOntoBacktrace.line(@expected_from) do generate_error unless expected_messages_received? || failed_fast? end end
def with(*args, &block)
cart.add(Book.new(:isbn => 1934356379))
# => failed expectation
cart.add(Book.new(:isbn => 1234567890))
cart.should_receive(:add).with(Book.new(:isbn => 1934356379)) { :success }
# => :success
cart.add(Book.new(:isbn => 1934356379))
# => :failure
cart.add(Book.new(:isbn => 1234567890))
cart.stub(:add).with(Book.new(:isbn => 1934356379)) { :success }
cart.stub(:add) { :failure }
@example
arguments.
A message expectation will fail if the message is received with different
message using `with` to constrain to specific arguments.
you should stub a default value first, and then stub or mock the same
With a stub, if the message might be received with other args as well,
arguments.
Constrains a stub or message expectation to invocations with specific
def with(*args, &block) if args.empty? raise ArgumentError, "`with` must have at least one argument. Use `no_args` matcher to set the expectation of receiving no arguments." end self.inner_implementation_action = block @argument_list_matcher = ArgumentListMatcher.new(*args) self end
def yield_receiver_to_implementation_block?
def yield_receiver_to_implementation_block? @yield_receiver_to_implementation_block end