I am trying to write the unit test case for the private route we created, using @azure/msal-react
below is the code for the private route
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import {
AuthenticatedTemplate,
UnauthenticatedTemplate,
} from '@azure/msal-react';
export const PrivateRoute = (props) => {
const {
component: Component,
...restProps
} = props;
if (!Component) return null;
return (
<Route
exact
{...restProps}
render={(routeRenderProps) => (
<>
<AuthenticatedTemplate>
<Component
{...routeRenderProps}
{...restProps}
/>
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<Redirect
to={{
pathname: '/auth/signin',
state: { from: routeRenderProps.location },
}}
/>
</UnauthenticatedTemplate>
</>
)}
/>
);
};
below is the unit test case I wrote using react testing library
import React from 'react';
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { MsalAuthenticationTemplate } from '@azure/msal-react';
import { PrivateRoute } from '../privateRoute';
describe('PrivateRoute', () => {
test('renders the component when the user is authenticated', () => {
const Component = () => <div>My Component</div>;
render(
<MemoryRouter initialEntries={['/']}>
<MsalAuthenticationTemplate>
<PrivateRoute
path="/"
component={Component}
/>
</MsalAuthenticationTemplate>
</MemoryRouter>,
);
const componentElement = screen.getByText('My Component');
expect(componentElement).toBeInTheDocument();
});
});
but this test case doesn't work, as it was not able to find the component.
pls refer to the attached image,
Could please help me to resolve this issue?
another test case I tried like this below, here I am setting an authentication status by passing a mockClient to the msal provider
import React from 'react';
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { MsalProvider } from '@azure/msal-react';
import { PrivateRoute } from '../privateRoute';
describe('PrivateRoute', () => {
test('renders the component when the user is authenticated', () => {
const Component = () => <div>My Component</div>;
// Create an instance of MsalProvider with a mocked instance
const mockClient = {
getAllAccounts: jest.fn(() => [{ name: 'Test User' }]),
};
render(
<MsalProvider instance={mockClient}>
<MemoryRouter initialEntries={['/']}>
<PrivateRoute path="/" component={Component} />
</MemoryRouter>
</MsalProvider>,
);
const componentElement = screen.getByText('My Component');
expect(componentElement).toBeInTheDocument();
});
});
but it shows the below error message
Found the way to set the authentication status
Please find the below code for it. msal-react-tester
this library helps to set the authentication status.
import React from 'react';
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { MsalProvider } from '@azure/msal-react';
import { MsalReactTester } from 'msal-react-tester';
import { PrivateRoute } from '../privateRoute';
describe('PrivateRoute', () => {
let msalTester;
beforeEach(async () => {
// new instance of msal tester for each test:
msalTester = new MsalReactTester();
// Ask msal-react-tester to handle and mock all msal-react processes:
await msalTester.spyMsal();
});
afterEach(async () => {
// reset msal-react-tester
await msalTester.resetSpyMsal();
});
test('renders the component when the user is authenticated', async () => {
const Component = () => <div>My Component</div>;
// Set the user as logged in
await msalTester.isLogged();
render(
<MsalProvider instance={msalTester.client}>
<MemoryRouter initialEntries={['/']}>
<PrivateRoute path="/" component={Component} />
</MemoryRouter>
</MsalProvider>,
);
// Wait for the authentication redirect to resolve
await msalTester.waitForRedirect();
const componentElement = screen.getByText('My Component');
expect(componentElement).toBeInTheDocument();
});
});