(
self: Self,
property: keyof Self,
descriptorOrFunction?:
| ((this: Self, ...args: Args) => Return)
| Omit<PropertyDescriptor, "configurable">,
)
| 150 | >; |
| 151 | }; |
| 152 | export function stub<Self, Args extends unknown[], Return>( |
| 153 | self: Self, |
| 154 | property: keyof Self, |
| 155 | descriptorOrFunction?: |
| 156 | | ((this: Self, ...args: Args) => Return) |
| 157 | | Omit<PropertyDescriptor, "configurable">, |
| 158 | ): Stub<Self, Args, Return> { |
| 159 | if ( |
| 160 | self[property] !== undefined && |
| 161 | typeof self[property] !== "function" && |
| 162 | (descriptorOrFunction === undefined || |
| 163 | typeof descriptorOrFunction === "function") |
| 164 | ) { |
| 165 | throw new MockError("Cannot stub: property is not an instance method"); |
| 166 | } |
| 167 | if (isSpy(self[property])) { |
| 168 | throw new MockError("Cannot stub: already spying on instance method"); |
| 169 | } |
| 170 | if ( |
| 171 | descriptorOrFunction !== undefined && |
| 172 | typeof descriptorOrFunction !== "function" && |
| 173 | descriptorOrFunction.get === undefined && |
| 174 | descriptorOrFunction.set === undefined |
| 175 | ) { |
| 176 | throw new MockError( |
| 177 | "Cannot stub: neither setter nor getter is defined", |
| 178 | ); |
| 179 | } |
| 180 | |
| 181 | const propertyDescriptor = Object.getOwnPropertyDescriptor(self, property); |
| 182 | if (propertyDescriptor && !propertyDescriptor.configurable) { |
| 183 | throw new MockError("Cannot stub: non-configurable instance method"); |
| 184 | } |
| 185 | const fake = |
| 186 | descriptorOrFunction && typeof descriptorOrFunction === "function" |
| 187 | ? descriptorOrFunction |
| 188 | : ((() => {}) as (this: Self, ...args: Args) => Return); |
| 189 | |
| 190 | const original = self[property] as unknown as ( |
| 191 | this: Self, |
| 192 | ...args: Args |
| 193 | ) => Return; |
| 194 | const calls: SpyCall<Self, Args, Return>[] = []; |
| 195 | let restored = false; |
| 196 | const stub = function (this: Self, ...args: Args): Return { |
| 197 | const call: SpyCall<Self, Args, Return> = { args }; |
| 198 | if (this) call.self = this; |
| 199 | try { |
| 200 | call.returned = fake.apply(this, args); |
| 201 | } catch (error) { |
| 202 | call.error = error as Error; |
| 203 | calls.push(call); |
| 204 | throw error; |
| 205 | } |
| 206 | calls.push(call); |
| 207 | return call.returned; |
| 208 | } as Stub<Self, Args, Return>; |
| 209 | Object.defineProperties(stub, { |
nothing calls this directly
no test coverage detected