Msal-react-tester - A tester package when using msal-react in your application

Last update: Jul 26, 2022

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.
{ // reset msal-react-tester msalTester.resetSpyMsal(); });">
let msalTester: MsalReactTester;

beforeEach(() => {
  // new instance of msal tester for each test:
  msalTester = new MsalReactTester(); 
  // or new MsalReactTester("Redirect") / new MsalReactTester("Popup")

  // Ask msal-react-tester to handle and mock all msal-react processes:
  msalTester.spyMsal();
});

afterEach(() => {
  // reset msal-react-tester
  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 msalTester.isNotLogged().
  • Mock an authenticated user, calling msalTester.isLogged().
  • Creates a 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 component during a first visit by an authenticated user:

test('Home page render correctly when user is not logged', async () => {

  // Mock a guest user, not yet authenticated:
  msalTester.isNotLogged();

  // Render the  component using a  
  // with the mock IPublicClientApplication instance:
  render(
    <MsalProvider instance={msalTester.client}>
      <MemoryRouter>
        <Layout>
          <HomePage />
        </Layout>
      </MemoryRouter>
    </MsalProvider>,
  );
  
  // Wait for msal-react-tester to handle events from msal-react:
  await msalTester.waitForRedirect();

  // Test your  component:
  expect(screen.getByText(/Please sign-in/)).toBeInTheDocument();
});

On the other side, you can test the same component assuming your user is "already logged", using msalTester.isLogged().

Testing a component during an authentication process:

If you want to test a component during the authentication process, you can use msalTester.waitForLogin():

test('Home page render correctly when user logs in', async () => {

  // Mock a guest user, not yet authenticated:
  msalTester.isNotLogged();

  // Render the  component using a  
  // with the mock IPublicClientApplication instance:
  render(
    <MsalProvider instance={msalTester.client}>
      <MemoryRouter>
        <Layout>
          <HomePage />
        </Layout>
      </MemoryRouter>
    </MsalProvider>,
  );

  // Wait for msal-react-tester to handle events from msal-react:
  await msalTester.waitForRedirect();

  // Getting the log in button.
  // Mock a user click to launch the log in process:
  const signin = screen.getByRole('button', { name: 'Sign In' });
  userEvent.click(signin);

  // Wait for msal-react-tester to handle the login process from msal-react:
  await msalTester.waitForLogin();

  // From here, your user is supposed to be logged in the component:
  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

GitHub

https://github.com/Mimetis/msal-react-tester
You might also like...

React-Application - The Real time chat application for chatting uisng socket.io

React-Application - The Real time chat application for chatting uisng socket.io

This is the Real time chat application for chatting uisng socket.io

May 9, 2022

Lazerpay-react - Lazerpay SDK allows you accept payments easily in your react application

Lazerpay-react - Lazerpay SDK allows you accept payments easily in your react application

Lazerpay Official react sdk Lazerpay SDK allows you accept payments easily in yo

Jul 25, 2022

This application is being constructed by combining small open source demos into one big application

This application is being constructed by combining small open source demos into one big application

Live Demo on Heroku If this doesn't work, it's probably because it exceeds Heroku's 500MB memory quota for the free tier. Sorry about that. It does wo

Dec 10, 2021

A simple boilerplate that helps you make your react application with Server Side Rendering & Localization support.

A simple boilerplate that helps you make your react application with Server Side Rendering & Localization support.

Phoenix React applications boilerplate A simple boilerplate that helps you make your react application with Server Side Rendering support. Getting sta

Jul 24, 2022

This is simple CRUD React & Redux application. You can create, update,delete your projects and also filter them by their priority

This is simple CRUD React & Redux application. You can create, update,delete your projects and also filter them by their priority

ProjectList This is simple CRUD React & Redux application.You can create,update,delete your projects and also filter them by their priority. Main page

Jul 5, 2021

A simple react native starter template that bootstraps development of your mobile application

A simple react native starter template that bootstraps development of your mobile application

rn-start-template A simple react native starter template that bootstraps development of your mobile application. What's inside React native 0.63 templ

Jan 15, 2022

TaxiApp-react-typescript - A simple taxi application that allows you to look for a taxi nearby your place

Taxi Application A simple taxi application that allows you to look for a taxi ne

Jan 10, 2022

Django + React Boilerplate for starting your SaaS application.

Django + React Boilerplate for starting your SaaS application.

DIY Django and React Boilerplate for SaaS It is do-it-yourself Django + React Boilerplate for starting your SaaS application. In existing boilerplates

Aug 1, 2022

F-Curator - An offline application that comes at you all day long, and curate your own web favorites

F-Curator - An offline application that comes at you all day long, and curate your own web favorites

F-Curator F-Curator is an offline application that comes at you all day long and

Jul 4, 2022
Comments
  • 1. Error using React 18

    error-react

    It seems to me that it is not compatible with react 18, I am using testing-library in version 13. I tried downgrading to 12.1.5 but it is not compatible with my version of react.

    Reviewed by jereef at 2022-07-26 14:45
  • 2. Vite

    • Upgrade to React 18
    • Because React 18, removing fluent (not yet compatible) and replaced with mui, in the samples.
    • Adding vitest test runner as an option
    Reviewed by Mimetis at 2022-07-27 12:26
ReservoirKit is a react package that makes it easy to add buying NFTs into your dApp. It's intuitive, responsive and customizable.

ReservoirKit is a react package that makes it easy to add buying NFTs into your dApp. It's intuitive, responsive and customizable.

Jul 28, 2022
Visualize your React components as you interact with your application.
Visualize your React components as you interact with your application.

Visualize your React components as you interact with your application. Setup Install React Scope from Chrome web store. (Important) Install React Deve

Jul 23, 2022
React Package Starter - a simple and slightly opinionated starter kit for developing and publishing React packages

React Package Starter This is a simple and slightly opinionated starter kit for developing and publishing React packages. It comes with a several pre-

Jul 1, 2022
An npm package that lets you jump right into coding React and Redux with universal (isomorphic) rendering. Only manage Express setups or Webpack configurations if you want to.

Universal Redux What and Why Universal Redux is an npm package that when used as a dependency in your project provides a universal (isomorphic) render

May 22, 2022
Initial directory structure and package.json as a seed for new React based projects.

React Project Seed This serves as a seed for starting new React projects. It's less of a boilerplate and more of a suggested directory structure that

Apr 7, 2020
an npm package for displaying and direct updating state for prototypes on React

React state-control A bunch of lightweight components for updating the model stored in React's stateful components for fast prototyping. Complete libr

May 7, 2022
React package that is an Ergo dApp Connector. Current supported wallets are Nautilus Wallet and SafeW.
React package that is an Ergo dApp Connector. Current supported wallets are Nautilus Wallet and SafeW.

Ergo dApp Connector React Package Table of Contents About The Project Built With Getting Started Prerequisites Installation Usage Contributing License

Jun 7, 2022
This package contains the source code of the React components for the Cloudscape Design System.

React components for Cloudscape Design System This package contains the source code of the React components for the Cloudscape Design System. Cloudsca

Aug 6, 2022
Personal Website UI Template using React-TypeScript. I hope, it will be helpful for your personal website that showcases your work as a software developer.

Personal Website Template Personal Website UI Template using React-TypeScript Class components Personal website can be about anything you want, includ

Jun 15, 2022
Jul 27, 2022