Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master

Stop calling methods on args passed to a stubbed method.

Any method call may mutate an object, so we can't safely call
anything on a passed argument.

This reverts the following PRs and commits:

* #871:
  * 8a0962a ("Reword comment to not use “external” twice.")
  * 52c69f1 ("Just use `Array#hash`.")
* #868:
  * ed3fb3b ("Provide a clear error when received message args are mutated.")
  * fc9e9a5 ("Ignore arg mutations for method calls we are not concerned with.")

This adds notes to the docs about using mutated args
with `have_received(…).with(…)`.

Fixes #892.
latest commit 8d071d5ca1
Myron Marston myronmarston authored
Failed to load latest commit information.
basics Stop calling methods on args passed to a stubbed method.
configuring_responses cuke for wrapping original implementation
mutating_constants Rewrite cucumber features.
old_syntax Treat `any_args` as an arg splat.
outside_rspec Fix standalone so it doesn’t infect other objects.
setting_constraints Update `any_args` docs to explain splat semantics.
step_definitions Rewrite cucumber features.
support Rewrite cucumber features.
verifying_doubles Add more specific "does not implement" messages.
working_with_legacy_code fix spelling error
.nav Put the scope cuke last in the basics section.

rspec-mocks helps to control the context in a code example by letting you set known return values, fake implementations of methods, and even set expectations that specific messages are received by an object.

You can do these three things on test doubles that rspec-mocks creates for you on the fly, or you can do them on objects that are part of your system.

Messages and Methods

Message and method are metaphors that we use somewhat interchangeably, but they are subtly different. In Object Oriented Programming, objects communicate by sending messages to one another. When an object receives a message, it invokes a method with the same name as the message.

Test Doubles

A test double is an object that stands in for another object in your system during a code example. Use the double method, passing in an optional identifier, to create one:

book = double("book")

Most of the time you will want some confidence that your doubles resemble an existing object in your system. Verifying doubles are provided for this purpose. If the existing object is available, they will prevent you from adding stubs and expectations for methods that do not exist or that have invalid arguments.

book = instance_double("Book", :pages => 250)

Verifying doubles have some clever tricks to enable you to both test in isolation without your dependencies loaded while still being able to validate them against real objects.

Method Stubs

A method stub is an instruction to an object (real or test double) to return a known value in response to a message:

allow(die).to receive(:roll) { 3 }

This tells the die object to return the value 3 when it receives the roll message.

Message Expectations

A message expectation is an expectation that an object should receive a specific message during the course of a code example:

describe Account do
  context "when closed" do
    it "logs an 'account closed' message" do
      logger = double()
      account =
      account.logger = logger

      expect(logger).to receive(:account_closed).with(account)


This example specifies that the account object sends the logger the account_closed message (with itself as an argument) when it receives the close message.


The documentation for rspec-mocks is a work in progress. We'll be adding Cucumber features over time, and clarifying existing ones. If you have specific features you'd like to see added, find the existing documentation incomplete or confusing, or, better yet, wish to write a missing Cucumber feature yourself, please submit an issue or a pull request.

Something went wrong with that request. Please try again.