diff --git a/spec/core/SpyRegistrySpec.js b/spec/core/SpyRegistrySpec.js index 53d6cd73..dc1b1b8b 100644 --- a/spec/core/SpyRegistrySpec.js +++ b/spec/core/SpyRegistrySpec.js @@ -108,5 +108,25 @@ describe("SpyRegistry", function() { expect(subject.spiedFunc).toBe(originalFunction); }); + + it("does not add a property that the spied-upon object didn't originally have", function() { + // IE 8 doesn't support `Object.create` + if (jasmine.getEnv().ieVersion < 9) { return; } + + var spies = [], + spyRegistry = new jasmineUnderTest.SpyRegistry({currentSpies: function() { return spies; }}), + originalFunction = function() {}, + subjectParent = {spiedFunc: originalFunction}; + + var subject = Object.create(subjectParent); + + expect(subject.hasOwnProperty('spiedFunc')).toBe(false); + + spyRegistry.spyOn(subject, 'spiedFunc'); + spyRegistry.clearSpies(); + + expect(subject.hasOwnProperty('spiedFunc')).toBe(false); + expect(subject.spiedFunc).toBe(originalFunction); + }) }); }); diff --git a/src/core/SpyRegistry.js b/src/core/SpyRegistry.js index aa7ee21a..15c31905 100644 --- a/src/core/SpyRegistry.js +++ b/src/core/SpyRegistry.js @@ -40,25 +40,34 @@ getJasmineRequireObj().SpyRegistry = function(j$) { throw new Error(methodName + ' is not declared writable or has no setter'); } - var spy = j$.createSpy(methodName, obj[methodName]); + var originalMethod = obj[methodName], + spiedMethod = j$.createSpy(methodName, originalMethod), + restoreStrategy; + + if (Object.prototype.hasOwnProperty.call(obj, methodName)) { + restoreStrategy = function() { + obj[methodName] = originalMethod; + }; + } else { + restoreStrategy = function() { + delete obj[methodName]; + }; + } currentSpies().push({ - spy: spy, - baseObj: obj, - methodName: methodName, - originalValue: obj[methodName] + restoreObjectToOriginalState: restoreStrategy }); - obj[methodName] = spy; + obj[methodName] = spiedMethod; - return spy; + return spiedMethod; }; this.clearSpies = function() { var spies = currentSpies(); for (var i = spies.length - 1; i >= 0; i--) { var spyEntry = spies[i]; - spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue; + spyEntry.restoreObjectToOriginalState(); } }; }