Skip to content

Testing

The router was designed to be testable. createMemoryHistory is the only piece you need to drive a router without a DOM environment beyond what your test renderer provides.

A typical test

tsx
import {render, screen} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import {createMemoryHistory, route, routingHooksFactory} from 'tss-route-lib';

const router = route('home', '/', () => <div>Home</div>)
  .at('user', '/users/:id', (p) => <div>User {p.id}</div>);
const {RouteProvider, useRouter, Link} = routingHooksFactory(router);

test('navigates to a user', async () => {
  const history = createMemoryHistory();
  function App() {
    return useRouter();
  }

  render(
    <RouteProvider history={history}>
      <Link route="user" params={{id: '1'}}>Go</Link>
      <App />
    </RouteProvider>,
  );

  expect(screen.getByText('Home')).toBeInTheDocument();
  await userEvent.click(screen.getByText('Go'));
  expect(history.location.pathname).toBe('/users/1');
  expect(screen.getByText('User 1')).toBeInTheDocument();
});

Inspecting state directly

MemoryHistory exposes index and entries for assertions:

ts
const history = createMemoryHistory();
history.push('/a');
history.push('/b');

expect(history.index).toBe(2);
expect(history.entries.map((e) => e.pathname)).toEqual(['/', '/a', '/b']);

history.back();
expect(history.index).toBe(1);
expect(history.action).toBe('POP');

Seeding initial state

For tests that start mid-flow, pass initialEntries and initialIndex:

ts
const history = createMemoryHistory({
  initialEntries: ['/list', '/users/1', '/users/1/posts/9'],
  initialIndex: 1,
});

// Starts at /users/1; back() goes to /list, forward() goes to /users/1/posts/9.

Pure rendering without React Testing Library

You don't have to render the tree. Routing and Router are usable directly:

ts
const router = route('user', '/users/:id', (p) => <div>{p.id}</div>);
router.buildUrl('user', {id: '42'});         // "/users/42"
router.render({pathname: '/users/42', search: '', hash: '', state: null, key: ''});

Use this for unit tests of param parsing or URL building without a DOM.

Released under the ISC License.