Sinon中stub.restore与stub.reset的区别及适用场景
Sinon:
stub.restore() vs stub.reset() — Differences & Use Cases Hey there! Let's break down the key differences between stub.restore() and stub.reset() in the Sinon testing framework, plus when you should reach for each one to keep your tests clean and isolated.
Core Differences
stub.restore()
- What it does: Completely removes the stub and restores the original method/property on the target object to its pre-stubbed state. After calling this, the original functionality is fully back—your stub no longer exists or intercepts calls.
- Think of it like: Uninstalling a replacement part and putting the original one back in place.
stub.reset()
- What it does: Resets only the internal state of the stub, not the stub itself. This clears:
- Call count (
stub.callCountgoes back to 0) - Recorded arguments (
stub.argsbecomes empty) - Any custom behaviors you set (like
stub.returns()orstub.callsFake(), which revert to the default stub behavior—usually returningundefined)
- Call count (
- Key note: The stub is still attached to the target object. Calls to the target method will still go through the stub, just with a fresh state.
- Think of it like: Erasing the history of a tool but keeping the tool itself ready to use again.
When to Use Each Method
Use stub.restore() when:
- You need to clean up after a test to prevent cross-test contamination. For example, if multiple tests stub the same global function or module method, restoring it ensures each test starts with the original implementation.
- You've stubbed a method that other tests rely on (like a database connection or API client). Failing to restore could break those tests by leaving the stub in place.
- You want to completely undo the stubbing operation—like when you're done with the stub and don't need it anymore in the current test suite context.
Use stub.reset() when:
- You're reusing the same stub multiple times within a single test case. For example, testing different scenarios where the stub is called with different arguments, and you need to reset its call history each time to validate new behavior.
- You want to reconfigure the stub's behavior without destroying and recreating it. Resetting lets you clear old state, then set up new returns/call fakes for the next part of your test.
Quick Example Code
Using restore()
const sinon = require('sinon'); const axios = require('axios'); test('fetches mock data', async () => { // Create stub to replace axios.get const getStub = sinon.stub(axios, 'get').resolves({ data: 'mock data' }); // Run test logic that calls axios.get... // Clean up: restore original axios.get functionality getStub.restore(); });
Using reset()
const sinon = require('sinon'); test('handles multiple stub invocations', () => { const calculateStub = sinon.stub().returns(10); // First test scenario expect(calculateStub(2, 3)).toBe(10); expect(calculateStub.callCount).toBe(1); // Reset state and reconfigure the stub calculateStub.reset(); calculateStub.returns(15); // Second test scenario expect(calculateStub(4, 5)).toBe(15); expect(calculateStub.callCount).toBe(1); // Count starts fresh after reset });
内容的提问来源于stack exchange,提问作者Fluit




