Skip to content

Make sinon.restoreObject idempotent #2736

Description

@icholy

Is your feature request related to a problem? Please describe.

In most cases, I want to use sinon.restoreObject(value) in a test hook like beforeEach/afterEach. However, not every single test case necessarily stubs value.

afterEach(() => {
    sinon.restoreObject(value);
})

it('should do x', () => {
    sinon.stub(value, 'foo').returns(123);
    // ...
});


it('should do y', () => {
    // no value stub
})

This will throw after the second test because value does not contain a stub.

Describe the solution you'd like

I want the sinon.restoreObject method to have symmetry with sinon.restore() and sandbox.restore(). Ie, passing an empty/un-mocked object should be a no-op.

Describe alternatives you've considered

Right now i have my own wrapper:

function restore(value) {
    if ('restore' in value && typeof value.restore === 'function') {
        value.restore()
    }
}

However, it doesn't handle nesting. Another alternative would be to leave sinon.restoreObject as-is and allow passing a value to sinon.restore(value).

Additional context

The strict behaviour was originally introduced here: #2092
I think the stricter behaviour makes sense for the other methods, but not for restoreObject.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions