javascriptreactjsjestjsreact-test-renderer

Keep "this" context when mocking Promise in function on component


I am having an issue where I am not able to reference this keyword via Jest when testing some logic in my componentDidMount method. So once I am inside the promise response, when I hover over this in this.props (or this.setState), it just shows undefined.

This is the Method in my App component:

componentDidMount() {
  myHttpService.getUser(this.props.userId).then(response => {
    if (response.user !== null) {
      this.setState({ user: response.user });
    } else {
      this.props.history.push('/login');
    }
  });
}

This is my unit test for that component:

it('push login route to history if no user is returned', () => {
  myHttpService.default.getUser = jest.fn(() =>
    Promise.resolve({ user: null }),
  );

  const result = renderer.create(
    <MemoryRouter>
      <App />
    </MemoryRouter>,
  );

  // Not sure how to check that route was pushed to history, trying to solve the this context issue first.
  // expect(?).toHaveBeenCalled();
});

Solution

  • Mock the service in your test file

    jest.mock('<path-to-your myHttpService>', () => {
      return function() {
        return { getUser: () => Promise.resolve({ user: null }) };
      };
    });
    

    You can do the following for the assertion with Jest

    let instance = result.getInstance();
    let history = instance.history;
    expect(history.location.pathname).to.equal('/login');
    

    Here is a complete working repo on github