I've got fairly simple react component (Link wrapper which adds 'active' class if route is active):
import React, { PropTypes } from 'react'; import { Link } from 'react-router'; const NavLink = (props, context) => { const isActive = context.router.isActive(props.to, true); const activeClass = isActive ? 'active' : ''; return ( <li className={activeClass}> <Link {...props}>{props.children}</Link> </li> ); } NavLink.contextTypes = { router: PropTypes.object, }; NavLink.propTypes = { children: PropTypes.node, to: PropTypes.string, }; export default NavLink;
How am I supposed to test it? My only attempt was:
import NavLink from '../index'; import expect from 'expect'; import { mount } from 'enzyme'; import React from 'react'; describe('<NavLink />', () => { it('should add active class', () => { const renderedComponent = mount(<NavLink to="/home" />, { router: { pathname: '/home' } }); expect(renderedComponent.hasClass('active')).toEqual(true); }); });
It doesn't work and returns TypeError: Cannot read property 'isActive' of undefined
. It definitely needs some router mocking, but I have no idea how to write it.
You can use the createMemoryHistory function and Router component to test it. Create a memory history with initial entries to simulate the current location, this way we don't rely on the real browser environment. After firing the click event, assert the pathname is changed correctly or not.
push with the new React Router Hooks using Jest, we can call jest. mock to mock the useHistory hook. import React from 'react'; import { MemoryRouter } from 'react-router-dom'; import { render, fireEvent } from '@testing-library/react'; import RouteNotFound from './NotFound'; const mockHistoryPush = jest. fn(); jest.
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.
Thanks @Elon Szopos for your answer but I manage to write something much more simple (following https://github.com/airbnb/enzyme/pull/62):
import NavLink from '../index'; import expect from 'expect'; import { shallow } from 'enzyme'; import React from 'react'; describe('<NavLink />', () => { it('should add active class', () => { const context = { router: { isActive: (a, b) => true } }; const renderedComponent = shallow(<NavLink to="/home" />, { context }); expect(renderedComponent.hasClass('active')).toEqual(true); }); });
I have to change mount
to shallow
in order not to evaluate Link
which gives me an error connected with the react-router TypeError: router.createHref is not a function
.
I would rather have "real" react-router than just an object but I have no idea how to create it.
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