Skip to content

Commit

Permalink
bug-13140-001 Re-added spyOn support for function exports exposed usi…
Browse files Browse the repository at this point in the history
…ng getters
  • Loading branch information
staplespeter committed Oct 14, 2022
1 parent 4f3f8db commit 780dc05
Showing 1 changed file with 44 additions and 38 deletions.
82 changes: 44 additions & 38 deletions packages/jest-mock/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1193,72 +1193,78 @@ export class ModuleMocker {
${this._typeOf(descriptor?.[accessType])} given instead`,
);
}
} else if (typeof descriptor.value !== 'function') {
} else if (
(descriptor.value && typeof descriptor.value !== 'function') ||
(descriptor.get && typeof descriptor.get !== 'function')
) {
throw new Error(
`Cannot spy the ${String(
methodKey,
)} property because it is not a function; ${this._typeOf(
descriptor.value,
descriptor.value ? descriptor.value : descriptor.get,
)} given instead`,
);
}

const isMethodOwner = Object.prototype.hasOwnProperty.call(
object,
methodKey,
);
let mock: Mock;

if (accessType == 'get' && descriptor['get']) {
const originalAccessor = descriptor['get'];
mock = this._makeComponent(
{
type: 'function',
},
() => {
descriptor![accessType] = originalAccessor;
if (accessType == 'get' && descriptor.get) {
const originalAccessor = descriptor.get;
mock = this._makeComponent({type: 'function'}, () => {
if (isMethodOwner) {
descriptor!.get = originalAccessor;
Object.defineProperty(object, methodKey, descriptor!);
},
);
} else {
delete object[methodKey];
}
});

descriptor[accessType] = mock;
descriptor.get = mock;
mock.mockImplementation(function (this: unknown) {
return originalAccessor.call(this);
});
Object.defineProperty(object, methodKey, descriptor);
} else if (accessType == 'set' && descriptor['set']) {
const originalAccessor = descriptor['set'];
mock = this._makeComponent(
{
type: 'function',
},
() => {
descriptor![accessType] = originalAccessor;
} else if (accessType == 'set' && descriptor.set) {
const originalAccessor = descriptor.set;
mock = this._makeComponent({type: 'function'}, () => {
if (isMethodOwner) {
descriptor!.set = originalAccessor;
Object.defineProperty(object, methodKey, descriptor!);
},
);
} else {
delete object[methodKey];
}
});

descriptor[accessType] = mock;
descriptor.set = mock;
mock.mockImplementation(function (this: unknown) {
return originalAccessor.call(this, arguments[0]);
});
Object.defineProperty(object, methodKey, descriptor);
} else if (descriptor.get) {
const originalGet = descriptor.get;
mock = this._makeComponent({type: 'function'}, () => {
descriptor!.get = originalGet;
Object.defineProperty(object, methodKey, descriptor!);
});
descriptor.get = () => mock;
Object.defineProperty(object, methodKey, descriptor);
} else {
const isMethodOwner = Object.prototype.hasOwnProperty.call(
object,
methodKey,
);
const original = descriptor;

mock = this._makeComponent(
{
type: 'function',
},
() => {
if (isMethodOwner) {
object[methodKey] = original.value;
} else {
delete object[methodKey];
}
},
);

mock = this._makeComponent({type: 'function'}, () => {
if (isMethodOwner) {
object[methodKey] = original.value;
} else {
delete object[methodKey];
}
});
// @ts-expect-error overriding original method with a Mock
object[methodKey] = mock;
mock.mockImplementation(function (this: unknown) {
Expand Down

0 comments on commit 780dc05

Please sign in to comment.