( self: Self, property: keyof Self, func?: (this: Self, ...args: Args) => Return, )
| 1053 | ) => GetReturnFromProp<Self, Prop>, |
| 1054 | ): Stub<Self, GetParametersFromProp<Self, Prop>, GetReturnFromProp<Self, Prop>>; |
| 1055 | export function stub< |
| 1056 | Self, |
| 1057 | Args extends unknown[], |
| 1058 | Return, |
| 1059 | >( |
| 1060 | self: Self, |
| 1061 | property: keyof Self, |
| 1062 | func?: (this: Self, ...args: Args) => Return, |
| 1063 | ): Stub<Self, Args, Return> { |
| 1064 | if (self[property] !== undefined && typeof self[property] !== "function") { |
| 1065 | throw new MockError( |
| 1066 | "Cannot stub: property is not an instance method", |
| 1067 | ); |
| 1068 | } |
| 1069 | if (isSpy(self[property])) { |
| 1070 | throw new MockError( |
| 1071 | "Cannot stub: already spying on instance method", |
| 1072 | ); |
| 1073 | } |
| 1074 | |
| 1075 | const propertyDescriptor = Object.getOwnPropertyDescriptor(self, property); |
| 1076 | if (propertyDescriptor && !propertyDescriptor.configurable) { |
| 1077 | throw new MockError("Cannot stub: non-configurable instance method"); |
| 1078 | } |
| 1079 | |
| 1080 | const fake = func ?? (() => {}) as (this: Self, ...args: Args) => Return; |
| 1081 | |
| 1082 | const original = self[property] as unknown as ( |
| 1083 | this: Self, |
| 1084 | ...args: Args |
| 1085 | ) => Return; |
| 1086 | const calls: SpyCall<Self, Args, Return>[] = []; |
| 1087 | let restored = false; |
| 1088 | const stub = function (this: Self, ...args: Args): Return { |
| 1089 | const call: SpyCall<Self, Args, Return> = { args }; |
| 1090 | if (this) call.self = this; |
| 1091 | try { |
| 1092 | call.returned = fake.apply(this, args); |
| 1093 | } catch (error) { |
| 1094 | call.error = error as Error; |
| 1095 | calls.push(call); |
| 1096 | throw error; |
| 1097 | } |
| 1098 | calls.push(call); |
| 1099 | return call.returned; |
| 1100 | } as Stub<Self, Args, Return>; |
| 1101 | Object.defineProperties(stub, { |
| 1102 | original: { |
| 1103 | enumerable: true, |
| 1104 | value: original, |
| 1105 | }, |
| 1106 | fake: { |
| 1107 | enumerable: true, |
| 1108 | value: fake, |
| 1109 | }, |
| 1110 | calls: { |
| 1111 | enumerable: true, |
| 1112 | value: calls, |
no test coverage detected