Одним из источников путаницы вокруг моков, является то, что моки могут быть с отслеживанием состояния.
Например, эта функция:
const fn = vi.fn()
fn('one')
fn('two')
fn.mock.calls
// [ ["one"], ["two"] ]В приведенном выше примере функция-заглушка fn имеет состояние, которое отслеживает все вызовы, сделанные к ней. Само состояние не является проблемой. На самом деле, вам это состояние нужно! Оно необходимо для проверки правильного количества вызовов и их аргументов во время теста.
Состояние начинает вызывать проблемы, как только с ним неправильно обращаются.
Когда оно изменяется или сохраняется, когда вы этого не ожидаете. Чрезвычайно распространенным примером неправильно управляемого состояния является следующее:
const listener = vi.fn()
test('calls the listener when the event is emitted', () => {
const emitter = new Emitter()
emitter.on('hello', listener)
emitter.emit('hello')
expect(listener).toHaveBeenCalledTimes(1)
})
test('does not call the listener after `.removeAllListeners()` has been called', () => {
const emitter = new Emitter()
emitter.on('hello', listener)
emitter.removeAllListeners()
emitter.emit('hello')
expect(listener).not.toHaveBeenCalled()
})Здесь нам нужно протестировать случаи для класса Emitter. Первый из них ожидает, что слушатель будет вызван при эмитировании события, а другой ожидает отсутствия вызовов слушателя, потому что все слушатели были удалены.
Чтобы это проверить, мы вводим мок функцию listener, чтобы проверять вызовы.
Но если мы запустим этот набор тестов, мы получим ошибку
