( object: T, key: K, accessor?: 'get' | 'set', )
| 276 | ? Mock<Required<T>[M]> |
| 277 | : never |
| 278 | export function spyOn<T extends object, K extends keyof T>( |
| 279 | object: T, |
| 280 | key: K, |
| 281 | accessor?: 'get' | 'set', |
| 282 | ): Mock<Procedure | Constructable> { |
| 283 | assert( |
| 284 | object != null, |
| 285 | 'The vi.spyOn() function could not find an object to spy upon. The first argument must be defined.', |
| 286 | ) |
| 287 | |
| 288 | assert( |
| 289 | typeof object === 'object' || typeof object === 'function', |
| 290 | 'Vitest cannot spy on a primitive value.', |
| 291 | ) |
| 292 | |
| 293 | const [originalDescriptorObject, originalDescriptor] = getDescriptor(object, key) || [] |
| 294 | assert( |
| 295 | originalDescriptor || key in object, |
| 296 | `The property "${String(key)}" is not defined on the ${typeof object}.`, |
| 297 | ) |
| 298 | let accessType: 'get' | 'set' | 'value' = accessor || 'value' |
| 299 | let ssr = false |
| 300 | |
| 301 | // vite ssr support - actual function is stored inside a getter |
| 302 | if ( |
| 303 | accessType === 'value' |
| 304 | && originalDescriptor |
| 305 | && originalDescriptor.value == null |
| 306 | && originalDescriptor.get |
| 307 | ) { |
| 308 | accessType = 'get' |
| 309 | ssr = true |
| 310 | } |
| 311 | |
| 312 | let original: Procedure | undefined |
| 313 | |
| 314 | if (originalDescriptor) { |
| 315 | original = originalDescriptor[accessType] |
| 316 | // weird Proxy edge case where descriptor's value is undefined, |
| 317 | // but there's still a value on the object when called |
| 318 | // https://github.com/vitest-dev/vitest/issues/9439 |
| 319 | if (original == null && accessType === 'value') { |
| 320 | original = object[key] as unknown as Procedure |
| 321 | } |
| 322 | } |
| 323 | else if (accessType !== 'value') { |
| 324 | original = () => object[key] |
| 325 | } |
| 326 | else { |
| 327 | original = object[key] as unknown as Procedure |
| 328 | } |
| 329 | |
| 330 | const originalImplementation = ssr && original ? original() : original |
| 331 | const originalType = typeof originalImplementation |
| 332 | |
| 333 | assert( |
| 334 | // allow only functions |
| 335 | originalType === 'function' |
nothing calls this directly
no test coverage detected