diff --git a/lib/sinon/sandbox.js b/lib/sinon/sandbox.js index c5642f15d..4e8a1bfe9 100644 --- a/lib/sinon/sandbox.js +++ b/lib/sinon/sandbox.js @@ -191,7 +191,13 @@ function Sandbox() { sandbox.injectedKeys.length = 0; }; - function getFakeRestorer(object, property, forceAssignment) { + /** + * Creates a restorer function for the property + * @param {object|Function} object + * @param {string} property + * @param {boolean} forceAssignment + */ + function getFakeRestorer(object, property, forceAssignment = false) { const descriptor = getPropertyDescriptor(object, property); const value = object[property]; @@ -229,11 +235,9 @@ function Sandbox() { * @param {object|Function} object * @param {string} property * @param {*} replacement a fake, stub, spy or any other value - * @param {object} [options] - * @param {boolean} options.forceAssignment allows you to force use of assignment in the presence of a setter * @returns {*} */ - sandbox.replace = function replace(object, property, replacement, options) { + sandbox.replace = function replace(object, property, replacement) { const descriptor = getPropertyDescriptor(object, property); if (typeof descriptor === "undefined") { @@ -248,18 +252,12 @@ function Sandbox() { throw new TypeError("Expected replacement argument to be defined"); } - if (!options?.forceAssignment) { - if (typeof descriptor.get === "function") { - throw new Error( - "Use sandbox.replaceGetter for replacing getters" - ); - } + if (typeof descriptor.get === "function") { + throw new Error("Use sandbox.replaceGetter for replacing getters"); + } - if (typeof descriptor.set === "function") { - throw new Error( - "Use sandbox.replaceSetter for replacing setters" - ); - } + if (typeof descriptor.set === "function") { + throw new Error("Use sandbox.replaceSetter for replacing setters"); } if (typeof object[property] !== typeof replacement) { @@ -275,7 +273,7 @@ function Sandbox() { // store a function for restoring the replaced property push( fakeRestorers, - getFakeRestorer(object, property, options?.forceAssignment) + getFakeRestorer(object, property) ); object[property] = replacement; @@ -283,6 +281,18 @@ function Sandbox() { return replacement; }; + sandbox.replace.usingAccessor = function replaceUsingAccessor(object, property, replacement) { + // store a function for restoring the replaced property + push( + fakeRestorers, + getFakeRestorer(object, property, true) + ); + + object[property] = replacement; + + return replacement; + } + sandbox.define = function define(object, property, value) { const descriptor = getPropertyDescriptor(object, property); diff --git a/test/sandbox-test.js b/test/sandbox-test.js index e2961e61d..72b904919 100644 --- a/test/sandbox-test.js +++ b/test/sandbox-test.js @@ -1115,7 +1115,7 @@ describe("Sandbox", function () { ); }); - it("should allow forcing assignment", function () { + it("should allow using assignment when replacing a value", function () { const sandbox = this.sandbox; let hiddenFoo = () => "original"; const object = { @@ -1129,9 +1129,7 @@ describe("Sandbox", function () { }; assert.equals(object.foo(), "original"); - sandbox.replace(object, "foo", sinonFake.returns("fake"), { - forceAssignment: true, - }); + sandbox.replace.usingAccessor(object, "foo", sinonFake.returns("fake")); assert.equals(object.foo(), "fake"); sandbox.restore(); assert.equals(object.foo(), "original");