msal-react-tester. A tester package when using msal-react in your application
About
The MSAL React Tester is a NPM package to allows you creating unit tests for any of your components that need to be authenticated (or not) using the msal-react package and Azure AD.
The MSAL React Tester package is able to run by default with different javascript test runners like:
The MSAL React Tester package allows you to test your components in any of these scenario:
- Testing a react component when a user "is not" authenticated.
- Testing a react component when a user "is" authenticated.
- Testing a react component when a user "tries" to log in.
- Testing a react component when a user "tries" to log out.
- Testing a react component when a user authentication request has "failed".
Prerequisites
- You are building a react application using Create React Application or vite.
- You are using
@azure/msal-react to authenticate your users on Azure AD.
- You are using the built in
@testing-library/react package to create and run your tests (you are basically using the built in "test": "react-scripts test" script to execute your tests).
- You want to create unit tests without having to depends on a connection to Azure AD.
- You want to run your tests in your CI/CD.
Installation
The MSAL React Tester package is available on NPM.
npm install --save-dev msal-react-tester
vitest
If you are using the vitest test runner, you need to add this to your config
import { MsalReactTesterPlugin } from 'msal-react-tester'
import { vi, expect } from 'vitest'
MsalReactTesterPlugin.init({
spyOn: vi.spyOn,
expect: expect,
resetAllMocks: vi.resetAllMocks
})
If you are using jest this step is not necessary.
Usage
Creates a [component].test.tsx and import the msal-react-tester package:
import { MsalReactTester } from 'msal-react-tester';
Initialization:
- Create a new instance of
MsalReactTester before each test.
- Depending on your setup, you can create your instance to mock a Redirect authentication or a Popup authentication.
- Call the
spyMsal() method to mock all the MSAL React required methods & events.
- Don not forget to call
resetSpyMsal after each test.
let msalTester: MsalReactTester;
beforeEach(() => {
msalTester = new MsalReactTester();
msalTester.spyMsal();
});
afterEach(() => {
msalTester.resetSpyMsal();
});
Testing a component without any interaction with the authentication process:
In each of your test, you can now:
- Mock an unauthenticated user, calling
await msalTester.isNotLogged().
- Mock an authenticated user, calling
await msalTester.isLogged().
- Creates a
<MsalProvider /> using the msalTester.client as the IPublicClientApplication instance.
- Call
msalTester.waitForRedirect() to let MSAL React Tester handling MSAL React processes
- Then makes any tests or assertions.
Here is an example where we are testing a <HomePage /> component during a first visit by an authenticated user:
test('Home page render correctly when user is not logged', async () => {
await msalTester.isNotLogged();
render(
<MsalProvider instance={msalTester.client}>
<MemoryRouter>
<Layout>
<HomePage />
</Layout>
</MemoryRouter>
</MsalProvider>,
);
await msalTester.waitForRedirect();
expect(screen.getByText(/Please sign-in/)).toBeInTheDocument();
});
On the other side, you can test the same component assuming your user is "already logged", using await msalTester.isLogged().
Testing a component during an authentication process:
If you want to test a component during the authentication process, you can use await msalTester.waitForLogin():
test('Home page render correctly when user logs in', async () => {
await msalTester.isNotLogged();
render(
<MsalProvider instance={msalTester.client}>
<MemoryRouter>
<Layout>
<HomePage />
</Layout>
</MemoryRouter>
</MsalProvider>,
);
await msalTester.waitForRedirect();
const signin = screen.getByRole('button', { name: 'Sign In' });
userEvent.click(signin);
await msalTester.waitForLogin();
expect(screen.getByRole('button',
{ name: msalTester.activeAccount.name })).toBeInTheDocument();
});
On the other side, if you want to test component during a log out process, use msalTester.waitForLogout()
Example
You will find a full example in the ../example folder.
Take a look on the pages tests:
root
├── example
├──── src
├────── pages
├──────── HomePage.test.tsx
├──────── SearchPage.test.tsx
License
Licensed under the MIT License.
Contact
Feel free to contact me through twitter : @sebpertus