Как сбросить или очистить шпиона в Jest?

У меня есть шпион, который используется в нескольких утверждениях в нескольких тестах в наборе.

Как очистить или сбросить шпиона, чтобы в каждом тесте метод, который перехватывает шпион, не вызывался?

Например, как сделать утверждение в 'does not run method' верным?

const methods = {
  run: () => {}
}

const spy = jest.spyOn(methods, 'run')

describe('spy', () => {
  it('runs method', () => {
    methods.run()
    expect(spy).toHaveBeenCalled() //=> true
  })

  it('does not run method', () => {
    // how to make this true?
    expect(spy).not.toHaveBeenCalled() //=> false
  })
})

Ответы

Ответ 1

Шпионские шпионы имеют тот же API, что и макеты. Документация для mocks находится здесь и определяет метод mockClear который:

Сбрасывает всю информацию, хранящуюся в mockFn.mock.calls и mockFn.mock.instances.

Часто это полезно, когда вы хотите очистить фиктивные данные об использовании между двумя утверждениями.

(акцент мой)

Таким образом, мы можем использовать mockClear для "сброса" шпиона. Используя ваш пример:

const methods = {
  run: () => {}
}

const spy = jest.spyOn(methods, 'run')

describe('spy', () => {
  it('runs method', () => {
    methods.run()
    expect(spy).toHaveBeenCalled() //=> true
    /* clean up the spy so future assertions
       are unaffected by invocations of the method
       in this test */
    spy.mockClear()
  })

  it('does not run method', () => {
    expect(spy).not.toHaveBeenCalled() //=> true
  })
})

Ответ 2

Спасибо @sdgluck за ответ, хотя я хотел бы добавить к этому ответу, что в моем случае я хотел получить четкое состояние после каждого теста, так как у меня есть несколько тестов с одним и тем же шпионом. Поэтому вместо вызова mockClear() в предыдущих тестах я переместил его в afterEach() следующим образом:

afterEach(() => {    
  jest.clearAllMocks();
});

И, наконец, мои тесты работают так, как они должны без вызова шпиона из предыдущего теста.

Ответ 3

Итерируя далее ответ @ghiscoding, вы можете указать clearMocks в конфигурации Jest, что эквивалентно вызову jest.clearAllMocks() между каждым тестом:

{
...
    clearMocks: true,
...
}

Смотрите документы здесь.