React-i18next: The Jest mock in the docs does not work for shallow rendering with Enzyme

Created on 8 Apr 2018  路  1Comment  路  Source: i18next/react-i18next

In the testing docs there is a recommendation to mock the react-i18next module like so:

jest.mock('react-i18next', () => ({
  // this mock makes sure any components using the translate HoC receive the t function as a prop
  translate: () => Component => props => <Component t={() => ''} {...props} />,
}));

This seems like a great solution because I am implementing my react components like so:

import { translate } from "react-i18next";

class MyComponent extends React.Component {
  render() {
    return (
      <p>Yay</p>
    )
  }
}

export default translate("MyComponent")(MyComponent);

Unfortunately, the mock interferes with enzyme's shallow rendering because it returns a new component that wraps the old component. As a result, enzyme's shallow rendering will only render the wrapper returned in the mock, props => <Component t={() => ''} {...props} />, and not the component itself.

For example, when I implement my test like so:

import React from "react";
import { shallow } from "enzyme";
import MyComponent from "../my-component"

jest.mock('react-i18next', () => ({
  // this mock makes sure any components using the translate HoC receive the t function as a prop
  translate: () => Component => props => <Component t={() => ''} {...props} />,
}));


describe("MyComponent test", () => {

  test("renders p tag", () => {
    const wrapper = shallow(<MyComponent/>);
    console.log("wrapper.debug():", wrapper.debug());
    expect(wrapper.find('p')).toHaveLength(1);
  });
}

the output of my wrapper.debug() should be:

wrapper.debug(): <p>Yay</p>

but instead I'm getting this:

wrapper.debug(): <MyComponent/>

and I think this is because the mock is returning a wrapper around MyComponent, instead of returning MyComponent itself.

Is there a way to fix the mock so that it binds the t prop without having to wrap the component within a new component?

Most helpful comment

I think I found an answer here, by using this mock:

jest.mock("react-i18next", () => ({
  // this mock makes sure any components using the translate HoC receive the t function as a prop
  translate: () => Component => {
    Component.defaultProps = { ...Component.defaultProps, t: () => "" };
    return Component;
  },
}));

Does this seem like a reasonable solution? It seems to work for me - now my tests with Enzyme's shallow renderer are passing :-)

I added a PR that updates the docs here: https://github.com/i18next/react-i18next-gitbook/pull/9

>All comments

I think I found an answer here, by using this mock:

jest.mock("react-i18next", () => ({
  // this mock makes sure any components using the translate HoC receive the t function as a prop
  translate: () => Component => {
    Component.defaultProps = { ...Component.defaultProps, t: () => "" };
    return Component;
  },
}));

Does this seem like a reasonable solution? It seems to work for me - now my tests with Enzyme's shallow renderer are passing :-)

I added a PR that updates the docs here: https://github.com/i18next/react-i18next-gitbook/pull/9

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tankpower1 picture tankpower1  路  3Comments

oyeanuj picture oyeanuj  路  3Comments

Flo-Slv picture Flo-Slv  路  4Comments

nicholasmaddren picture nicholasmaddren  路  4Comments

leandrocamacho picture leandrocamacho  路  4Comments