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.
Testing components which rely on the context can be a little tricky. What I did was to write a wrapper that I used in my tests.
You can find the wrapper below:
Here you can see a sample usage:
And it should work as you would expect.
You can use https://github.com/pshrmn/react-router-test-context for that exact purpose
"Create a pseudo context object that duplicates React Router's context.router structure. This is useful for shallow unit testing with Enzyme."
After installing it, you will be able to do something like
For react router v4 you can use a
<MemoryRouter>
. Example with AVA and Enzyme:Thanks @Elon Szopos for your answer but I manage to write something much more simple (following https://github.com/airbnb/enzyme/pull/62):
I have to change
mount
toshallow
in order not to evaluateLink
which gives me an error connected with the react-routerTypeError: 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.