9

I have this module with a function in it:

const utils = {
  redirectTo(url) {
    if (url) {
      window.location = url;
    }
  },
};

export default utils;

It is used somewhere in a React component like this:

import utils from '../../lib/utils';

componentWillUpdate() {
  this.redirectTo('foo')
}

Now I want to check that the value that redirectTo is called with equals foo.

  it('should redirect if no rights', () => {
    const mockRedirectFn = jest.fn();
    utils.redirectTo = mockRedirectFn;

    mount(
      <SomeComponent />,
    );

    expect(mockRedirectFn).toBeCalled();
    expect(mockRedirectFn).toBeCalledWith('foo');
    console.log(mockRedirectFn.mock);
    // { calls: [], instances: [] }
  });

Thats what I've got and it does not work. How do I do this?

Joshua
  • 3,055
  • 3
  • 22
  • 37
SM79
  • 1,234
  • 2
  • 15
  • 33

2 Answers2

12

You have to mock the lib/utils module like this:

import utils from '../../lib/utils';
jest.mock('../../lib/utils', () => ({
  redirect: jest.fn()
}))

it('should redirect if no rights', () => {
  mount(
    <SomeComponent />,
  );
  expect(utils.redirect).toHaveBeenCalledWith();
});

This will replace the module with a mock that just returns {redirect:jest.fn()}. This module is also imported into you test where you then can access the spy for redirect and test on this that it was called with the correct parameter.

Anil
  • 21,730
  • 9
  • 73
  • 100
Andreas Köberle
  • 106,652
  • 57
  • 273
  • 297
4

This is what I ended up using:

 it('should redirect if no rights', () => {

    // this way we mock only one method: redirectTo
    jest.mock('lib/utils', () => {
      const original = require.requireActual('lib/utils');
      original.default.redirectTo = jest.fn();
      return original;
    });

    const redirectTo = require.requireMock('lib/utils').default.redirectTo;

    mount(
      <SomeComponent />,
    );

    expect(redirectTo).toHaveBeenCalled();
  });
SM79
  • 1,234
  • 2
  • 15
  • 33