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?
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
Most helpful comment
I think I found an answer here, by using this mock:
Does this seem like a reasonable solution? It seems to work for me - now my tests with Enzyme's
shallowrenderer are passing :-)I added a PR that updates the docs here: https://github.com/i18next/react-i18next-gitbook/pull/9