Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

816
Visualizações
Matcher error: received value must be a mock or spy function

I'm writing tests (with Jest and React Testing Library) for a form React component. I have a method that runs on form submit:

const onSubmit = (data) => {
  // ...
  setIsPopupActive(true);
  // ...
};

and useEffect that runs after isPopupActive change, so also on submit:

useEffect(() => {
  if (isPopupActive) {
    setTimeout(() => {
      setIsPopupActive(false);
    }, 3000);
  }
}, [isPopupActive]);

In the test, I want to check, whether the popup disappears after 3 seconds. So here's my test:

it('Closes popup after 3 seconds', async () => {
    const nameInput = screen.getByPlaceholderText('Imię');
    const emailInput = screen.getByPlaceholderText('Email');
    const messageInput = screen.getByPlaceholderText('Wiadomość');
    const submitButton = screen.getByText('Wyślij');

    jest.useFakeTimers();

    fireEvent.change(nameInput, { target: { value: 'Test name' } });
    fireEvent.change(emailInput, { target: { value: 'test@test.com' } });
    fireEvent.change(messageInput, { target: { value: 'Test message' } });
    fireEvent.click(submitButton);

    const popup = await waitFor(() =>
      screen.getByText(/Wiadomość została wysłana/)
    );

    await waitFor(() => {
      expect(popup).not.toBeInTheDocument(); // this passes

      expect(setTimeout).toHaveBeenCalledTimes(1);
      expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 3000);
    });
  });

However, I'm getting the error:

expect(received).toHaveBeenCalledTimes(expected)

Matcher error: received value must be a mock or spy function

Received has type:  function
Received has value: [Function setTimeout]

What am I doing wrong?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

In your case setTimeout is not a mock or spy, rather, it's a real function. To make it a spy, use const timeoutSpy = jest.spyOn(window, 'setTimeout'). And use timeoutSpy in the assertion.

You could also test not the fact of calling the setTimeout function, but assert that setIsPopupActive was called once, and with false. For this you might need to do jest.runOnlyPendingTimers() or jest.runAllTimers()

over 4 years ago · Santiago Trujillo Relatório

0

Jest 27 has breaking changes for fakeTimers. It seems Jest contributors doesn't update documentation on time. This comment on Github issues confirms it. Moreover, here related PR.

Well, you can solve your problem by two ways.

  1. Configure Jest to use legacy fake timers. In jest.config.js you can add line (but it not works for me):
module.exports = {
 // many of lines omited
 timers: 'legacy'
};
  1. Configure legacy fake timers for individually test suite, or even test:
jest.useFakeTimers('legacy');
describe('My awesome logic', () => {
// blah blah blah
});

It's preferably to use new syntax based on @sinonjs/fake-timers. But I can't find working example for Jest, so I'll update this answer as soon as possible.

over 4 years ago · Santiago Trujillo Relatório

0

The below approach worked

beforeEach(() => {
  jest.spyOn(global, 'setTimeout');
});

afterEach(() => {
  global.setTimeout.mockRestore();
});

it('Test if SetTimeout is been called', {
  global.setTimeout.mockImplementation((callback) => callback());
  expect(global.setTimeout).toBeCalledWith(expect.any(Function), 7500);
})
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda