diff --git a/spec/core/SpyRegistrySpec.js b/spec/core/SpyRegistrySpec.js index 0511e2a8..4ce31ddd 100644 --- a/spec/core/SpyRegistrySpec.js +++ b/spec/core/SpyRegistrySpec.js @@ -89,5 +89,22 @@ describe("SpyRegistry", function() { expect(subject.spiedFunc).toBe(originalFunction); }); + + it("does not add a property that the spied-upon object didn't originally have", function() { + 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 25c9b343..7215ca67 100644 --- a/src/core/SpyRegistry.js +++ b/src/core/SpyRegistry.js @@ -33,25 +33,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 = 0; i < spies.length; i++) { var spyEntry = spies[i]; - spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue; + spyEntry.restoreObjectToOriginalState(); } }; }