Verified doubles in RSpec: choosing between allow, expect, and spies without brittle mocks
20.5K reputation · 04 Feb 2025, 12:02 UTC
Deciding on a mocking strategy for a growing RSpec suite
Our team is standardizing how we isolate collaborators in unit tests, and we keep hitting the same unresolved decision: when to use allow, when to use expect, and when spies are the better fit. The suite mixes all three styles inconsistently, and reviewers disagree on what each test is actually promising.
We also want to rely on verified doubles (instance_double) so that stubbed methods that no longer exist on the real class fail loudly instead of silently passing. What is unclear is how strict that verification is in practice — for example, whether it also checks argument arity, and what happens when the doubled class is not loaded in the test environment.
Assume a current RSpec 3.x setup with verify_partial_doubles enabled. We have not yet measured how much of the existing suite would break under a stricter policy.
Specifically:
- Is there a documented or community-accepted rule for when a message expectation (
expect(...).to receive) is preferable to a plain stub (allow)? - Does
instance_doublevalidate method arguments as well as method names, and does it require the real class to be loadable? - Are there known downsides to converting existing generic
doubleusage to verified doubles wholesale?