Liero
Liero

Reputation: 27338

Testing react component within react router

I want to test react component:

export class IdentityPage extends React.Component<PageProps, State> {
    constructor(props: PageProps) {
        super(props);
    }

    componentDidMount() { this.reload(this.props.routeParams.id); }
    render(){....}
}

which is used in react router like this:

<Router history={hashHistory}>
    <Route path="/">
        <Route path="Identities">
            <Route path=":action/:id" component={IdentityPage} />
        </Route>
    </Route>
</Router>

However, the test fails with:

Cannot read property 'id' of undefined

when I try to run:

let pageProps: PageProps = {
    params: {
        action: "view",
        id: "0"
    }
};
let instance = TestUtils.renderIntoDocument(React.createElement(IdentityPage, pageProps));

Upvotes: 1

Views: 3137

Answers (2)

Liero
Liero

Reputation: 27338

I had to change pageProps to include routeParams:

let pageProps: PageProps = {
    params: { action: "view", id: "0" },
    routeParams: { action: "view", id: "0" },
};

let instance = TestUtils.renderIntoDocument(React.createElement(IdentityPage, pageProps));

In the page I was simply accessing routeParams instead of params

Upvotes: 0

Dawid Karabin
Dawid Karabin

Reputation: 5293

If you use react-router v4, you can use <MemoryRouter ...> and wrap your component with the <Route ...> component.

MemoryRouter keeps the history of your “URL” in memory (does not read or write to the address bar). Useful in tests and non-browser environments.

As example (from react-router repository)

<MemoryRouter initialEntries={[ '/sushi/california' ]}>
  <Route path="/sushi/:roll" render={({ match }) => {
    return <div>{match.url}</div>
  }}/>
</MemoryRouter>

So in your case

let instance = TestUtils.renderIntoDocument(
  <MemoryRouter initialEntries={['view/0']}>
    <Route path=":action/:id" component={IdentityPage} />
  </MemoryRouter>
);

Upvotes: 4

Related Questions