Throw if spying has no effect
This provides a useful diagnostic in cases where assigning to a property is a no-op, like localStorage in Firefox and Safari 17. See #2036 and #2007.
This commit is contained in:
@@ -9454,6 +9454,16 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
|||||||
|
|
||||||
obj[methodName] = spiedMethod;
|
obj[methodName] = spiedMethod;
|
||||||
|
|
||||||
|
// Check if setting the property actually worked. Some objects, such as
|
||||||
|
// localStorage in Firefox and later Safari versions, have no-op setters.
|
||||||
|
if (obj[methodName] !== spiedMethod) {
|
||||||
|
throw new Error(
|
||||||
|
j$.formatErrorMsg('<spyOn>')(
|
||||||
|
`Can't spy on ${methodName} because assigning to it had no effect`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return spiedMethod;
|
return spiedMethod;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,30 @@ describe('SpyRegistry', function() {
|
|||||||
}).not.toThrowError(/is not declared writable or has no setter/);
|
}).not.toThrowError(/is not declared writable or has no setter/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('throws if assigning to the property is a no-op', function() {
|
||||||
|
const scope = {};
|
||||||
|
|
||||||
|
function original() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.defineProperty(scope, 'myFunc', {
|
||||||
|
get() {
|
||||||
|
return original;
|
||||||
|
},
|
||||||
|
set() {}
|
||||||
|
});
|
||||||
|
|
||||||
|
const spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||||
|
createSpy: createSpy
|
||||||
|
});
|
||||||
|
expect(function() {
|
||||||
|
spyRegistry.spyOn(scope, 'myFunc');
|
||||||
|
}).toThrowError(
|
||||||
|
"<spyOn> : Can't spy on myFunc because assigning to it had no effect"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('overrides the method on the object and returns the spy', function() {
|
it('overrides the method on the object and returns the spy', function() {
|
||||||
const originalFunctionWasCalled = false,
|
const originalFunctionWasCalled = false,
|
||||||
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
spyRegistry = new jasmineUnderTest.SpyRegistry({
|
||||||
|
|||||||
@@ -84,6 +84,16 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
|||||||
|
|
||||||
obj[methodName] = spiedMethod;
|
obj[methodName] = spiedMethod;
|
||||||
|
|
||||||
|
// Check if setting the property actually worked. Some objects, such as
|
||||||
|
// localStorage in Firefox and later Safari versions, have no-op setters.
|
||||||
|
if (obj[methodName] !== spiedMethod) {
|
||||||
|
throw new Error(
|
||||||
|
j$.formatErrorMsg('<spyOn>')(
|
||||||
|
`Can't spy on ${methodName} because assigning to it had no effect`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return spiedMethod;
|
return spiedMethod;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user