I'm using Enzyme's shallow method to test a component which uses the useParams
hook to get an ID from the URL params.
I'm trying to mock the useParams
hook so that it does't call the actual method, but it doesn't work. I'm still getting TypeError: Cannot read property 'match' of undefined
, so it calls the actual useParams
, and not my mock.
My component:
import React from 'react';
import { useParams } from 'react-router-dom';
export default () => {
const { id } = useParams();
return <div>{id}</div>;
};
Test:
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import React from 'react';
import Header from './header';
import { shallow } from 'enzyme';
Enzyme.configure({ adapter: new Adapter() });
describe('<Header />', () => {
jest.mock('react-router-dom', () => ({
useParams: jest.fn().mockReturnValue({ id: '123' }),
}));
it('renders', () => {
const wrapper = shallow(<Header />);
expect(wrapper).toBeTruthy();
});
});
Thank you!
To mock the useHistory hook in Jest, we can call jest. mock with a function to return the return value of useHistory . jest. mock("react-router-dom", () => ({ useHistory: () => ({ push: jest.
To mock a React component, the most straightforward approach is to use the jest. mock function. You mock the file that exports the component and replace it with a custom implementation. Since a component is basically a function, the mock should also return a function.
This works for me to mock useParams and change values for each unit test within the same file:
import React from "react";
import { render } from "@testing-library/react";
import Router from "react-router-dom";
import Component from "./Component";
jest.mock("react-router-dom", () => ({
...jest.requireActual("react-router-dom"),
useParams: jest.fn(),
}));
const createWrapper = () => {
return render(<Cases />);
};
describe("Component Page", () => {
describe("Rendering", () => {
it("should render cases container", () => {
jest.spyOn(Router, 'useParams').mockReturnValue({ id: '1234' })
const wrapper = createWrapper();
expect(wrapper).toMatchSnapshot();
});
it("should render details container", () => {
jest.spyOn(Router, 'useParams').mockReturnValue({ id: '5678' })
const wrapper = createWrapper();
expect(wrapper).toMatchSnapshot();
});
});
});
Just declare useParams
as jest.fn()
outside describe() and then change its values in each unit test with jest.spyOn
I am not sure why, also couldn't find it in the docs of react-router library, but changing react-router-dom
to react-router
in both tests and implementation worked for me.
So it becomes something like this:
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import React from 'react';
import Header from './header';
import { shallow } from 'enzyme';
Enzyme.configure({ adapter: new Adapter() });
describe('<Header />', () => {
jest.mock('react-router', () => ({
useParams: jest.fn().mockReturnValue({ id: '123' }),
}));
it('renders', () => {
const wrapper = shallow(<Header />);
expect(wrapper).toBeTruthy();
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With