Jest how to assert that function is not called

Jestjs

Jestjs Problem Overview


In Jest there are functions like tobeCalled or toBeCalledWith to check if a particular function is called. Is there any way to check that a function is not called?

Jestjs Solutions


Solution 1 - Jestjs

Just use not.

expect(mockFn).not.toHaveBeenCalled()

See the jest documentation

Solution 2 - Jestjs

not did not work for me, throwing a Invalid Chai property: toHaveBeenCalled

But using toHaveBeenCalledTimes with zero does the trick:

expect(mock).toHaveBeenCalledTimes(0)

Solution 3 - Jestjs

Please follow the documentation from jest: https://jestjs.io/docs/en/mock-functions#mock-property

> All mock functions have this special .mock property, which is where data about how the function has been called and what the function returned is kept. The .mock property also tracks the value of this for each call, so it is possible to inspect this as well: [...] > > These mock members are very useful in tests to assert how these functions get called, instantiated, or what they returned:

// The function was called exactly once
expect(someMockFunction.mock.calls.length).toBe(1);

Or...

// The function was not called
expect(someMockFunction.mock.calls.length).toBe(0);

Solution 4 - Jestjs

Recent versions of Jest (22.x and onwards) collect quite decent statistics of mock functions calls, just check out their docs.

The calls property shows you the number of calls, the arguments passed to the mock, the result returned out of it and whatnot. You can access it directly, as a property of mock (e.g. in a way how @Christian Bonzelet suggested in his answer):

// The function was called exactly once
expect(someMockFunction.mock.calls.length).toBe(1);

// The first arg of the first call to the function was 'first arg'
expect(someMockFunction.mock.calls[0][0]).toBe('first arg');

// The second arg of the first call to the function was 'second arg'
expect(someMockFunction.mock.calls[0][1]).toBe('second arg');

I personally prefer this way as it gives you more flexibility and keeps code cleaner in case if you test for different inputs that produce a different number of calls.

However, you can also use shorthand aliases for Jest's expect since recently (spy matchers aliases PR). I guess .toHaveBeenCalledTimes would suit fine here:

test('drinkEach drinks each drink', () => {
  const drink = jest.fn();
  drinkEach(drink, ['lemon', 'octopus']);
  expect(drink).toHaveBeenCalledTimes(2); // or check for 0 if needed
});

In rare cases, you might even want to consider writing your own fixture that'd do the counting. It could be useful if you're heavy on conditioning or working with state, for example.

Hope this helps!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSachinView Question on Stackoverflow
Solution 1 - Jestjszer0chainView Answer on Stackoverflow
Solution 2 - JestjsBarnabyView Answer on Stackoverflow
Solution 3 - JestjsChristian BonzeletView Answer on Stackoverflow
Solution 4 - JestjsVladimir SalinView Answer on Stackoverflow