jest assert a function have been called twice and both times with particular argument

Viewed 1143

I am testing a Vue component that dispatches an action(functionx) on mount. The same action(functionx) is dispatched when a particular refresh button is clicked. I am testing the behavior of that refresh button - that is the vuex dispatch action is called with argument 'functionx'. Here is my test:

   it('makes an api call to server when refresh button is clicked', () => {
      store.dispatch = jest.fn();

      const wrapper = mount(Categories, {
         sync: false,
         store,
         localVue
      });

      const refreshButton = wrapper.find('span.fa-sync');
      refreshButton.trigger('click');

      expect(store.dispatch).toHaveBeenCalledWith('categoryStore/fetchCategories');
   })
});

which passes. Now since the same action is dispatched initially when the component is mounted. So in total dispatch is called twice. I know I can use .toHaveBeenNthCalledWith(nthCall, arg1, arg2, ....) to check that dispatch was called both times with same argument, but for that I will have to write two expect statements, like below:

expect(store.dispatch).toHaveBeenNthCalledWith(1, 'categoryStore/fetchCategories');
expect(store.dispatch).toHaveBeenNthCalledWith(2, 'categoryStore/fetchCategories');

Is there any way I can achieve the above thing in one statement? Any matcher function or any property on the expect object that can be used?

1 Answers

Sadly there's currently no easy matcher for this situation (list of matchers).

You could do it "manually" using the .mock parameter, something like this:

function assertFunctionWasCalledTimesWith(jestFunction, times, argument) {
    expect(jestFunction.mock.calls.filter((call) => call[0] === argument).length)
        .toBe(times)
}

(Using the filter method makes the times assertion only take into account the calls that have given argument)

Using the above function you could assert your code like this:

assertFunctionWasCalledTimesWith(store.dispatch, 2, 'categoryStore/fetchCategories')

Of course, the message when the test fails won't be very descriptive, but it works, anyway.

Related