Replies: 1 comment
-
|
I know this question is from years ago but this is my approach: import { expect, vi, describe, it } from 'vitest';
import { render, screen, act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { PokemonList } from './PokemonList';
describe('PokemonList comnponent', () => {
it('should when the page changes update the page param but keep the query param', async () => {
expect.assertions(6);
// This spy will allow us to intercept and assert all navigations
const navigationSpy = vi.fn();
render(
<MockRouter
path="/pokedex"
initialLocation="/pokedex?page=13&query=bulb"
navigationSpy={navigationSpy}
>
<PokemonList />
</MockRouter>
);
// Click the next page button on the pagination
const nextButton = await screen.findByLabelText('Go to next page');
await userEvent.click(nextButton);
// We now expect a wouter navigation to have occurred
expect(navigationSpy).toHaveBeenCalledTimes(1);
expect(navigationSpy).toHaveBeenLastCalledWith({
url: '/pokedex?page=14&query=bulb',
action: 'REPLACE',
});
});
});The import {
ReactNode
} from 'react';
import { Mock, vi } from 'vitest';
import {
Route,
Router,
Switch
} from 'wouter';
import { memoryLocation } from 'wouter/memory-location';
type Props = {
/**
* Optionally: the initial url / location the mock router should start on
*
* @default '/'
*/
initialLocation?: string;
/**
* Optionally: the path that the rendered Route should have. Should
* match the normal route the component has in the real application.
*
* @default '/'
*/
path?: string;
/**
* Optionally: a spy which is called whenever a navigation occurs.
*/
navigationSpy?: Mock;
/**
* The tested component, or another mock wrapper
*/
children: ReactNode;
/**
* Whether or not the MockRouter will render a <Switch> component.
*
* Should be set to `false` when testing components which render
* routes themselves.
*
* @default true
*/
renderRoutes?: boolean;
};
/**
* The MockRouter component can be used to mock the wouter router.
* This way the entire application does not need to be loaded
* each time the presence of the router is needed in the tests.
*/
export function MockRouter(props: Props) {
const {
children,
initialRoute = '/',
path = '/',
navigationSpy = vi.fn(),
renderRoutes = true
} = props;
const { hook, searchHook } = memoryLocation({
path: initialRoute
});
// Wrap `hook` that came from memoryLocation so we can make the navigation spy work.
function useCustomHook() {
// Take apart the original 'hook' from the `memoryLocation`.
const [location, navigate] = hook();
// Now we intercept each change in navigation
function interceptor(...args: unknown[]) {
// First pick out the url of the new location / route
const url = args[0];
// Next we like to know if the route was REPLACED or PUSH.
const options = args[1] as undefined | { replace?: boolean };
const replace = options?.replace ?? false;
// Call the navigation spy so the test can assert on navigation
navigationSpy({
action: replace ? 'REPLACE' : 'PUSH',
url
});
// Finally simply allow `memoryLocation` to handle the navigation
// now that we have spied upon it.
// @ts-expect-error This works since `memoryLocation` provides a valid navigation
navigate(...args);
}
// Return the current location from the `memoryLocation`, but
// provide our `interceptor` as the function to change navigation.
return [location, interceptor];
}
return (
// @ts-expect-error The useCustomHook works as a hook prop
<Router hook={useCustomHook} searchHook={searchHook}>
{renderRoutes ? (
<Switch>
<Route path={path}>{children}</Route>
<Route>MockRouter: no route found, this is a catch all</Route>
</Switch>
) : (
children
)}
</Router>
);
} |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Does anyone know where I can find documentation/forum posts discussing the testing approach for Wouter and the best way to test routes?
Beta Was this translation helpful? Give feedback.
All reactions