RSpec-Mocks: instance_double consistency during credential isolation
0 reputation · 08 Sept 2024, 10:49 UTC
0 reputation · 08 Sept 2024, 10:49 UTC
When isolating integration tests from production credentials, instance_double is used to ensure that stubs remain consistent with the actual class definitions of API wrappers or credential managers. This prevents the tests from passing against a mock interface that no longer exists in the production codebase.
A design challenge arises when the credential-providing class is modified or updated. While verified doubles catch method signature mismatches, there is uncertainty regarding the most effective way to prevent state leakage when these doubles are defined in shared contexts or global hooks across a large suite.
before(:all) versus before(:each) blocks?30775 reputation · 08 Sept 2024, 17:51 UTC
RSpec automatically clears verified doubles created in before(:each) by running its built‑in after(:each) hook. The mock registry is flushed after every example, so a double defined in before(:each) never sees state from a previous test.
When a double is created in before(:all), it lives for the entire example group. RSpec does not reset the mock registry until the group finishes, meaning the double can be reused by subsequent examples in the same group – and, if the same double is referenced in other groups that share the same before(:all) block, it can leak across unrelated examples.
let or before(:each) for doubles. This guarantees a fresh instance for every example and keeps the registry clean automatically.before(:all) (e.g., expensive setup), add an after(:each) hook that resets the mock configuration:
before(:all) do
@api = instance_double('ExternalApi')
allow(@api).to receive(:fetch).and_return(...)
end
after(:each) do
RSpec::Mocks::Configuration.instance.reset
end
before(:all) hook. That would wipe out stubs defined in other example groups that legitimately share state.verify_doubles enabled. It ensures that any signature mismatch is caught during the example’s teardown.Run a small suite that defines a double in before(:all) and observe that a later example can still call it. Then add the after(:each) reset hook and confirm the double is cleared.
Do you currently have any before(:all) blocks that create instance_double objects? If so, adding an after(:each) reset hook is the safest way to avoid leakage.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.