tinyspy
minimal fork of nanospy, with more features π΅π»ββοΈ
A 7KB
package for minimal and easy testing with no dependencies.
This package was created for having a tiny spy library to use in vitest
, but it can also be used in jest
and other test environments.
Installing
// with npm
npm install -D tinyspy
// with pnpm
pnpm install -D tinyspy
// with yarn
yarn install -D tinyspy
Usage
Warning! Does not support ESM mocking. You can use
tinyspy
withvitest
, who performs additional transformations to make ESM mocking work.
spy
Simplest usage would be:
const fn = (n: string) => n + '!'
const spied = spy(fn)
spied('a')
console.log(spied.called) // true
console.log(spied.callCount) // 1
console.log(spied.calls) // [['a']]
console.log(spied.results) // [['ok', 'a!']]
console.log(spied.returns) // ['a!']
You can reset calls, returns, called and callCount with reset
function:
const spied = spy((n: string) => n + '!')
spied('a')
console.log(spied.called) // true
console.log(spied.callCount) // 1
console.log(spied.calls) // [['a']]
console.log(spied.returns) // ['a.']
spied.reset()
console.log(spied.called) // false
console.log(spied.callCount) // 0
console.log(spied.calls) // []
console.log(spied.returns) // []
If you have async implementation, you need to await
the method to get awaited results (if you don't, you will get a Promise
inside results
):
const spied = spy(async (n: string) => n + '!')
const promise = spied('a')
console.log(spied.called) // true
console.log(spiet.returns) // [Promise]
await promise
console.log(spiet.returns) // ['a!']
spyOn
All
spy
methods are available onspyOn
.
You can spy on an object's method or setter/getter with spyOn
function.
let apples = 0
const obj = {
getApples: () => 13,
}
const spy = spyOn(obj, 'getApples', () => apples)
apples = 1
console.log(obj.getApples()) // prints 1
console.log(spy.called) // true
console.log(spy.returns) // [1]
let apples = 0
let fakedApples = 0
const obj = {
get apples() {
return apples
},
set apples(count) {
apples = count
},
}
const spyGetter = spyOn(obj, { getter: 'apples' }, () => fakedApples)
const spySetter = spyOn(obj, { setter: 'apples' }, (count) => {
fakedApples = count
})
obj.apples = 1
console.log(spySetter.called) // true
console.log(spySetter.calls) // [[1]]
console.log(obj.apples) // 1
console.log(fakedApples) // 1
console.log(apples) // 0
console.log(spyGetter.called) // true
console.log(spyGetter.returns) // [1]
You can reassign mocked function and restore mock to it's original implementation with restore
method:
const obj = {
fn: (n: string) => n + '!',
}
const spied = spyOn(obj, 'fn').willCall((n) => n + '.')
obj.fn('a')
console.log(spied.returns) // ['a.']
spied.restore()
obj.fn('a')
console.log(spied.returns) // ['a!']
You can even make an attribute into a dynamic getter!
let apples = 0
const obj = {
apples: 13,
}
const spy = spyOn(obj, { getter: 'apples' }, () => apples)
apples = 1
console.log(obj.apples) // prints 1
You can restore spied function to it's original value with restore
method:
let apples = 0
const obj = {
getApples: () => 13,
}
const spy = spyOn(obj, 'getApples', () => apples)
console.log(obj.getApples()) // 0
obj.restore()
console.log(obj.getApples()) // 13