Class: RSpec::Mocks::MessageExpectation

### Home Classes Methods

### In Files

- lib/rspec/mocks/message_expectation.rb

### Parent

Object

### Methods

- ::new
- #actual_received_count_matters?
- #advise
- #and_call_original
- #and_raise
- #and_return
- #and_throw
- #and_yield
- #any_number_of_times
- #at_least
- #at_most
- #called_max_times?
- #description
- #exactly
- #expectation_count_type
- #expected_args
- #expected_messages_received?
- #generate_error
- #ignoring_args?
- #increase_actual_received_count!
- #invoke
- #matches?
- #matches_at_least_count?
- #matches_at_most_count?
- #matches_exact_count?
- #matches_name_but_not_args
- #negative?
- #negative_expectation_for?
- #never
- #once
- #ordered
- #raise_out_of_order_error
- #similar_messages
- #times
- #twice
- #verify_messages_received
- #with

### Class/Module Index

Quicksearch

- RSpec
- RSpec::Mocks
- RSpec::Mocks::AllowanceTarget
- RSpec::Mocks::AmbiguousReturnError
- RSpec::Mocks::AndCallOriginalImplementation
- RSpec::Mocks::AndReturnImplementation
- RSpec::Mocks::AndYieldImplementation
- RSpec::Mocks::AnyInstance
- RSpec::Mocks::AnyInstance::Chain
- RSpec::Mocks::AnyInstance::Chain::Customizations
- RSpec::Mocks::AnyInstance::ExpectationChain
- RSpec::Mocks::AnyInstance::MessageChains
- RSpec::Mocks::AnyInstance::PositiveExpectationChain
- RSpec::Mocks::AnyInstance::Recorder
- RSpec::Mocks::AnyInstance::StubChain
- RSpec::Mocks::AnyInstance::StubChainChain
- RSpec::Mocks::AnyInstanceAllowanceTarget
- RSpec::Mocks::AnyInstanceExpectationTarget
- RSpec::Mocks::ArgumentListMatcher
- RSpec::Mocks::ArgumentMatchers
- RSpec::Mocks::ArgumentMatchers::AnyArgMatcher
- RSpec::Mocks::ArgumentMatchers::AnyArgsMatcher
- RSpec::Mocks::ArgumentMatchers::BooleanMatcher
- RSpec::Mocks::ArgumentMatchers::DuckTypeMatcher
- RSpec::Mocks::ArgumentMatchers::EqualityProxy
- RSpec::Mocks::ArgumentMatchers::HashExcludingMatcher
- RSpec::Mocks::ArgumentMatchers::HashIncludingMatcher
- RSpec::Mocks::ArgumentMatchers::InstanceOf
- RSpec::Mocks::ArgumentMatchers::KindOf
- RSpec::Mocks::ArgumentMatchers::MatcherMatcher
- RSpec::Mocks::ArgumentMatchers::NoArgsMatcher
- RSpec::Mocks::ArgumentMatchers::RegexpMatcher
- RSpec::Mocks::Configuration
- RSpec::Mocks::Constant
- RSpec::Mocks::ConstantMutator
- RSpec::Mocks::ConstantMutator::BaseMutator
- RSpec::Mocks::ConstantMutator::ConstantHider
- RSpec::Mocks::ConstantMutator::DefinedConstantReplacer
- RSpec::Mocks::ConstantMutator::UndefinedConstantSetter
- RSpec::Mocks::ConstantStubber
- RSpec::Mocks::Deprecation
- RSpec::Mocks::ErrorGenerator
- RSpec::Mocks::ExampleMethods
- RSpec::Mocks::ExampleMethods::ExpectHost
- RSpec::Mocks::ExpectationTarget
- RSpec::Mocks::Implementation
- RSpec::Mocks::InstanceExec
- RSpec::Mocks::InstanceMethodStasher
- RSpec::Mocks::Matchers
- RSpec::Mocks::Matchers::HaveReceived
- RSpec::Mocks::Matchers::Receive
- RSpec::Mocks::Matchers::Receive::Customization
- RSpec::Mocks::MessageExpectation
- RSpec::Mocks::MethodDouble
- RSpec::Mocks::MethodDouble::ProcWithBlock
- RSpec::Mocks::Mock
- RSpec::Mocks::MockExpectationError
- RSpec::Mocks::OrderGroup
- RSpec::Mocks::Proxy
- RSpec::Mocks::ProxyForNil
- RSpec::Mocks::RecursiveConstMethods
- RSpec::Mocks::Space
- RSpec::Mocks::StubChain
- RSpec::Mocks::Syntax
- RSpec::Mocks::TargetBase
- RSpec::Mocks::TestDouble
- RSpec::Mocks::Version
- Marshal

No matching classes.

# RSpec::Mocks::MessageExpectation

### Attributes

argument_list_matcher[W]
error_generator[RW]

@private

expected_from[W]
expected_received_count[W]
implementation[RW]

@private

message[R]

### Public Class Methods

new(error_generator, expectation_ordering, expected_from, method_double, expected_received_count=1, opts={}, &implementation_block) click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 12
    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
      @message = @method_double.method_name
      @actual_received_count = 0
      @expected_received_count = expected_received_count
      @argument_list_matcher = ArgumentListMatcher.new(ArgumentMatchers::AnyArgsMatcher.new)
      @order_group = expectation_ordering
      @at_least = @at_most = @exactly = nil
      @args_to_yield = []
      @failed_fast = nil
      @eval_context = nil

      @implementation = Implementation.new
      self.inner_implementation_action = implementation_block
    end

### Public Instance Methods

actual_received_count_matters?() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 424
    def actual_received_count_matters?
      @at_least || @at_most || @exactly
    end

advise(*args) click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 252
    def advise(*args)
      similar_messages << args
    end

and_call_original() click to toggle source

Tells the object to delegate to the original unmodified method when it receives the message.

@note This is only available on partial mock objects.

@example

    counter.should_receive(:increment).and_call_original
    original_count = counter.count
    counter.increment
    expect(counter.count).to eq(original_count + 1)

    # File lib/rspec/mocks/message_expectation.rb, line 101
    def and_call_original
      if @method_double.object.is_a?(RSpec::Mocks::TestDouble)
        @error_generator.raise_only_valid_on_a_partial_mock(:and_call_original)
      else
        @implementation = AndCallOriginalImplementation.new(@method_double.original_method)
      end
    end

and_raise(exception = RuntimeError, message = nil) click to toggle source

@overload and_raise @overload and_raise(ExceptionClass) @overload and_raise(ExceptionClass, message) @overload and_raise(exception_instance)

Tells the object to raise an exception when the message is received.

@note

    When you pass an exception class, the MessageExpectation will raise
    an instance of it, creating it with `exception` and passing `message`
    if specified.  If the exception class initializer requires more than
    one parameters, you must pass in an instance and not the class,
    otherwise this method will raise an ArgumentError exception.

@example

    car.stub(:go).and_raise
    car.stub(:go).and_raise(OutOfGas)
    car.stub(:go).and_raise(OutOfGas, "At least 2 oz of gas needed to drive")
    car.stub(:go).and_raise(OutOfGas.new(2, :oz))

    # File lib/rspec/mocks/message_expectation.rb, line 130
    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

and_return(*values, &implementation) click to toggle source

@overload and_return(value) @overload and_return(first_value, second_value) @overload and_return(&block)

Tells the object to return a value when it receives the message. Given more than one value, the first value is returned the first time the message is received, the second value is returned the next time, etc, etc.

If the message is received more times than there are values, the last value is received for every subsequent call.

The block format is still supported, but is unofficially deprecated in favor of just passing a block to the stub method.

@example

    counter.stub(:count).and_return(1)
    counter.count # => 1
    counter.count # => 1

    counter.stub(:count).and_return(1,2,3)
    counter.count # => 1
    counter.count # => 2
    counter.count # => 3
    counter.count # => 3
    counter.count # => 3
    # etc

    # Supported, but ...
    counter.stub(:count).and_return { 1 }
    counter.count # => 1

    # ... this is prefered
    counter.stub(:count) { 1 }
    counter.count # => 1

    # File lib/rspec/mocks/message_expectation.rb, line 73
    def and_return(*values, &implementation)
      if negative?
        RSpec.deprecate "`and_return` on a negative message expectation"
      end

      @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

and_throw(*args) click to toggle source

@overload and_throw(symbol) @overload and_throw(symbol, object)

Tells the object to throw a symbol (with the object if that form is used) when the message is received.

@example

    car.stub(:go).and_throw(:out_of_gas)
    car.stub(:go).and_throw(:out_of_gas, :level => 0.1)

    # File lib/rspec/mocks/message_expectation.rb, line 149
    def and_throw(*args)
      self.terminal_implementation_action = Proc.new { throw(*args) }
      nil
    end

and_yield(*args, &block) click to toggle source

Tells the object to yield one or more args to a block when the message is received.

@example

    stream.stub(:open).and_yield(StringIO.new)

    # File lib/rspec/mocks/message_expectation.rb, line 160
    def and_yield(*args, &block)
      yield @eval_context = Object.new.extend(RSpec::Mocks::InstanceExec) if block
      @args_to_yield << args
      self.initial_implementation_action = AndYieldImplementation.new(@args_to_yield, @eval_context, @error_generator)
      self
    end

any_number_of_times(&block) click to toggle source

Allows an expected message to be received any number of times.

    # File lib/rspec/mocks/message_expectation.rb, line 364
    def any_number_of_times(&block)
      RSpec.deprecate "any_number_of_times", :replacement => "stub"
      self.inner_implementation_action = block
      @expected_received_count = :any
      self
    end

at_least(n, &block) click to toggle source

Constrain a message expectation to be received at least a specific number of times.

@example

    dealer.should_receive(:deal_card).at_least(9).times

    # File lib/rspec/mocks/message_expectation.rb, line 328
    def at_least(n, &block)
      if n == 0
        RSpec.deprecate "at_least(0) with should_receive", :replacement => "stub"
      end

      self.inner_implementation_action = block
      set_expected_received_count :at_least, n
      self
    end

at_most(n, &block) click to toggle source

Constrain a message expectation to be received at most a specific number of times.

@example

    dealer.should_receive(:deal_card).at_most(10).times

    # File lib/rspec/mocks/message_expectation.rb, line 344
    def at_most(n, &block)
      self.inner_implementation_action = block
      set_expected_received_count :at_most, n
      self
    end

called_max_times?() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 201
    def called_max_times?
      @expected_received_count != :any &&
        !@at_least &&
        @expected_received_count > 0 &&
        @actual_received_count >= @expected_received_count
    end

description() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 272
    def description
      @error_generator.describe_expectation(@message, @expected_received_count, @actual_received_count, *expected_args)
    end

exactly(n, &block) click to toggle source

Constrain a message expectation to be received a specific number of times.

@example

    dealer.should_receive(:deal_card).exactly(10).times

    # File lib/rspec/mocks/message_expectation.rb, line 316
    def exactly(n, &block)
      self.inner_implementation_action = block
      set_expected_received_count :exactly, n
      self
    end

expectation_count_type() click to toggle source

    # File lib/rspec/mocks/message_expectation.rb, line 265
    def expectation_count_type
      return :at_least if @at_least
      return :at_most if @at_most
      return nil
    end

expected_args() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 33
    def expected_args
      @argument_list_matcher.expected_args
    end

expected_messages_received?() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 222
    def expected_messages_received?
      ignoring_args? || matches_exact_count? || matches_at_least_count? || matches_at_most_count?
    end

generate_error() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 257
    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

ignoring_args?() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 227
    def ignoring_args?
      @expected_received_count == :any
    end

increase_actual_received_count!() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 429
    def increase_actual_received_count!
      @actual_received_count += 1
    end

invoke(parent_stub, *args, &block) click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 173
    def invoke(parent_stub, *args, &block)
      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

matches?(message, *args) click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 168
    def matches?(message, *args)
      @message == message && @argument_list_matcher.args_match?(*args)
    end

matches_at_least_count?() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 232
    def matches_at_least_count?
      @at_least && @actual_received_count >= @expected_received_count
    end

matches_at_most_count?() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 237
    def matches_at_most_count?
      @at_most && @actual_received_count <= @expected_received_count
    end

matches_exact_count?() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 242
    def matches_exact_count?
      @expected_received_count == @actual_received_count
    end

matches_name_but_not_args(message, *args) click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 209
    def matches_name_but_not_args(message, *args)
      @message == message and not @argument_list_matcher.args_match?(*args)
    end

negative?() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 196
    def negative?
      @expected_received_count == 0 && !@at_least
    end

negative_expectation_for?(message) click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 419
    def negative_expectation_for?(message)
      @message == message && negative?
    end

never() click to toggle source

Expect a message not to be received at all.

@example

    car.should_receive(:stop).never

    # File lib/rspec/mocks/message_expectation.rb, line 376
    def never
      ErrorGenerator.raise_double_negation_error("expect(obj)") if negative?
      @expected_received_count = 0
      self
    end

once(&block) click to toggle source

Expect a message to be received exactly one time.

@example

    car.should_receive(:go).once

    # File lib/rspec/mocks/message_expectation.rb, line 387
    def once(&block)
      self.inner_implementation_action = block
      set_expected_received_count :exactly, 1
      self
    end

ordered(&block) click to toggle source

Expect messages to be received in a specific order.

@example

    api.should_receive(:prepare).ordered
    api.should_receive(:run).ordered
    api.should_receive(:finish).ordered

    # File lib/rspec/mocks/message_expectation.rb, line 411
    def ordered(&block)
      self.inner_implementation_action = block
      @order_group.register(self)
      @ordered = true
      self
    end

raise_out_of_order_error() click to toggle source

    # File lib/rspec/mocks/message_expectation.rb, line 276
    def raise_out_of_order_error
      @error_generator.raise_out_of_order_error @message
    end

similar_messages() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 247
    def similar_messages
      @similar_messages ||= []
    end

times(&block) click to toggle source

Syntactic sugar for `exactly`, `at_least` and `at_most`

@example

    dealer.should_receive(:deal_card).exactly(10).times
    dealer.should_receive(:deal_card).at_least(10).times
    dealer.should_receive(:deal_card).at_most(10).times

    # File lib/rspec/mocks/message_expectation.rb, line 357
    def times(&block)
      self.inner_implementation_action = block
      self
    end

twice(&block) click to toggle source

Expect a message to be received exactly two times.

@example

    car.should_receive(:go).twice

    # File lib/rspec/mocks/message_expectation.rb, line 398
    def twice(&block)
      self.inner_implementation_action = block
      set_expected_received_count :exactly, 2
      self
    end

verify_messages_received() click to toggle source

@private

    # File lib/rspec/mocks/message_expectation.rb, line 214
    def verify_messages_received
      generate_error unless expected_messages_received? || failed_fast?
    rescue RSpec::Mocks::MockExpectationError => error
      error.backtrace.insert(0, @expected_from)
      Kernel::raise error
    end

with(*args, &block) click to toggle source

Constrains a stub or message expectation to invocations with specific arguments.

With a stub, if the message might be received with other args as well, you should stub a default value first, and then stub or mock the same message using `with` to constrain to specific arguments.

A message expectation will fail if the message is received with different arguments.

@example

    cart.stub(:add) { :failure }
    cart.stub(:add).with(Book.new(:isbn => 1934356379)) { :success }
    cart.add(Book.new(:isbn => 1234567890))
    # => :failure
    cart.add(Book.new(:isbn => 1934356379))
    # => :success

    cart.should_receive(:add).with(Book.new(:isbn => 1934356379)) { :success }
    cart.add(Book.new(:isbn => 1234567890))
    # => failed expectation
    cart.add(Book.new(:isbn => 1934356379))
    # => passes

    # File lib/rspec/mocks/message_expectation.rb, line 304
    def with(*args, &block)
      self.inner_implementation_action = block if block_given? unless args.empty?
      @argument_list_matcher = ArgumentListMatcher.new(*args, &block)
      self
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.