Koby
Koby

Reputation: 33

Test fails when using LinkContainer from react-router-bootstrap

So I am making a ReactJS app which includes reactstrap, react-router and react-router-bootstrap. The problem is that when I test components which contain LinkContainer, the following error occurs, making my unit tests fail:

console.error node_modules\prop-types\checkPropTypes.js:19 Warning: Failed context type: The context router is marked as required in LinkContainer, but its value is undefined. in LinkContainer (at Header.js:27)

Could anyone please help me out? This is the code, in header.js for example:

import { LinkContainer } from "react-router-bootstrap";
import { ROUTE_POKEDEX } from "../../constants/constants";

export default class Header extends Component {
  constructor(props) {
    super(props);

    this.toggle = this.toggle.bind(this);
    this.state = {
      isOpen: false
    };
  }

  toggle() {
    this.setState({
      isOpen: !this.state.isOpen
    });
  }

  render() {
    return (
      <Container fluid className="header">
        <Navbar expand="md">
          <LinkContainer to={ROUTE_POKEDEX}>
            <NavbarBrand>Pokédex</NavbarBrand>
          </LinkContainer>
          <NavbarToggler onClick={this.toggle} />
        </Navbar>
      </Container>
    );
  }
}

test.js

import Header from "./Header";

it("renders without crashing", () => {
  const div = document.createElement("div");
  ReactDOM.render(<Header />, div);
  ReactDOM.unmountComponentAtNode(div);
});

it("has valid snapshot", () => {
  const tree = renderer.create(<Header />).toJSON();
  expect(tree).toMatchSnapshot();
});

Upvotes: 1

Views: 1157

Answers (1)

Eddie Padin
Eddie Padin

Reputation: 695

The problem is the LinkContainer component needs to be wrapped by Router, hence the error in your unit tests (Router doesn't get called when the individual component is being rendered in your test). Possible solution is using <MemoryRouter>.
From the docs:

Starting at specific routes

supports the initialEntries and initialIndex props, so you can boot up an app (or any smaller part of an app) at a specific location.

See: https://reacttraining.com/react-router/core/guides/testing/starting-at-specific-routes

Possible solution in the op's test case scenario would be to do something like this in the unit test when rendering the component (untested):
ReactDOM.render(<MemoryRouter><Header /></MemoryRouter>, div);

Upvotes: 1

Related Questions