-
Notifications
You must be signed in to change notification settings - Fork 1
Testing Routing
Oftentimes you may wish to test that your application is routing appropriately. This section lays out the different scenarios related to testing routing.
It is important to note that in the test environment, IonReactRouter
when paired with IonRouterOutlet
results in the following output on JSDOM
<body>
<div>
<ion-router-outlet />
</div>
</body>
This results in all test cases failing. Therefore for the test, environment, instead of using IonReactRouter
, you can use the Routers provided by react router e.g. Router
, BrowserRouter
or MemoryRouter
. The next section discusses the differences between these three routers.
TLDR; use Router
when you need access to the history
object (usually for asserting on history.location.pathname
), else use MemoryRouter
.
Testing URL navigation
You need access to the history
object so Router
would be the best choice as it takes it as a props. To create the history object you can use createMemoryHistory
provided by the history
package.
it("should take user to the appropriate URL", () => {
const history = createMemoryHistory({ initialEntries: ["/home"] });
render(
<Router history={history}>
<MainRouter />
</Router>
);
expect(history.location.pathname).toEqual("/home");
});
Testing that the correct UI is loaded
In this case you may not need access to the history object so MemoryRouter
would be adequate.
it("should show user the contents of Home", () => {
render(
<MemoryRouter initialEntries={["/home"]}>
<MainRouter />
</MemoryRouter>
);
expect(screen.getByTestId(/home/i));
});
However, do note that when using MemoryRouter
you cannot test for URL change. Therefore in most scenarios when we want to assert that both the URL as well as the content has changed we just use Router
Why not just test our components as follows:
window.history.pushState({}, "", '/');
return render(
<AuthProvider initialAuthState={false}>
<BrowserRouter>
<MainRouter />
</BrowserRouter>
</AuthProvider>
);
...
expect(window.location.pathname).toBe('/login')
This works, however, you need to find a way to ensure test isolation because the same window object is used in subsequent tests. This means when you print out window.history.length
you would see an increasing value for every test in which window.history.pushState was called. The object cannot be cleared or reset apparently due to security reasons. You could mock out the window object if you really wanted though but using Router
while passing in our own history
seems to be the simpler solution.
https://testing-library.com/docs/example-react-router/ https://github.com/ReactTraining/history/blob/v4/docs/GettingStarted.md