diff --git a/packages/enzyme-test-suite/test/Utils-spec.jsx b/packages/enzyme-test-suite/test/Utils-spec.jsx index 62ed2c339..4df0186c8 100644 --- a/packages/enzyme-test-suite/test/Utils-spec.jsx +++ b/packages/enzyme-test-suite/test/Utils-spec.jsx @@ -576,5 +576,18 @@ describe('Utils', () => { expect(target.incrementAndGet()).to.equal(4); }); }); + it('should be able to restore the property descriptor', () => { + const obj = {}; + const descriptor = { + configurable: true, + enumerable: true, + writable: true, + value: () => {}, + }; + Object.defineProperty(obj, 'method', descriptor); + const spy = spyMethod(obj, 'method'); + spy.restore(); + expect(Object.getOwnPropertyDescriptor(obj, 'method')).to.deep.equal(descriptor); + }); }); }); diff --git a/packages/enzyme/package.json b/packages/enzyme/package.json index 1f815333b..487b6e2dd 100644 --- a/packages/enzyme/package.json +++ b/packages/enzyme/package.json @@ -36,6 +36,7 @@ "dependencies": { "cheerio": "^1.0.0-rc.2", "function.prototype.name": "^1.0.3", + "has": "^1.0.1", "is-subset": "^0.1.1", "lodash": "^4.17.4", "object-is": "^1.0.1", diff --git a/packages/enzyme/src/Utils.js b/packages/enzyme/src/Utils.js index 18ef53ec2..f8d5e5188 100644 --- a/packages/enzyme/src/Utils.js +++ b/packages/enzyme/src/Utils.js @@ -3,6 +3,7 @@ import isEqual from 'lodash/isEqual'; import is from 'object-is'; import entries from 'object.entries'; import functionName from 'function.prototype.name'; +import has from 'has'; import configuration from './configuration'; import validateAdapter from './validateAdapter'; @@ -270,7 +271,11 @@ export function cloneElement(adapter, el, props) { export function spyMethod(instance, methodName) { let lastReturnValue; const originalMethod = instance[methodName]; - const hasOwn = Object.hasOwnProperty.call(instance, methodName); + const hasOwn = has(instance, methodName); + let descriptor; + if (hasOwn) { + descriptor = Object.getOwnPropertyDescriptor(instance, methodName); + } Object.defineProperty(instance, methodName, { configurable: true, enumerable: false, @@ -283,9 +288,13 @@ export function spyMethod(instance, methodName) { return { restore() { if (hasOwn) { - /* eslint-disable no-param-reassign */ - instance[methodName] = originalMethod; - /* eslint-enable no-param-reassign */ + if (descriptor) { + Object.defineProperty(instance, methodName, descriptor); + } else { + /* eslint-disable no-param-reassign */ + instance[methodName] = originalMethod; + /* eslint-enable no-param-reassign */ + } } else { /* eslint-disable no-param-reassign */ delete instance[methodName];