Jest: Difference between revisions

From bibbleWiki
Jump to navigation Jump to search
No edit summary
 
(63 intermediate revisions by the same user not shown)
Line 1: Line 1:
=Naming Test=
=Introduction=
This is a page to introduce Jest. Facebook employs a lot of the people who develop jest and can be and is used for test in other frameworks.<br>
<br>
Example code can be found at [[https://github.com/danielstern/isomorphic-react here]]
 
=Choices=
Popular tools for testing are Enzyme and Jasmine/Mocha. Jest is built on top of Jasmine/Mocha. Jest works with or without React and has a great assertion library.
==Why Not Enzyme==
This has over 200+ issues open and 26 of these are bugs. Jest is recommended by the react team.
==Jest vs Mocha==
Jest and Mocha both run tests sync and async but jest also has the following features.
*Spies (stubbing methods to spy)
*Snapshot testing
*Module mocking (stubbing objects)
=Getting Started=
==Running==
We can run jest on it's own or continually with watch mode
<syntaxhighlight lang="js">
jest --watch
</syntaxhighlight>
At least one "it" block must be found or jest will return an error.
==Code Coverage==
With Jest we can get a report by typing
<syntaxhighlight lang="js">
npm test  -- --coverage
</syntaxhighlight>
 
==Naming Test==
The file names must be recognized as a test.
<syntaxhighlight lang="bash">
  __tests__/*.js
  __tests__/*.js
  *.spec.js
  *.spec.js
  *.test.js
  *.test.js
</syntaxhighlight>
==Example Test in Jest==
<syntaxhighlight lang="js">
Describe is the suite, it is the test
describe("The question list ", ()=> {
    it ("should display a list of items", ()=> {
        expect(2+2).toEqual(4);
    })
    it ("should display a list of items", ()=> {
        expect(2+4).toEqual(6);
    })
})
</syntaxhighlight>
==Setup and Teardown==
This can be done using before each and before all.
<syntaxhighlight lang="js">
BeforeEach BeforeAll
beforeAll(()=>{
  console.log("Hello");
});
</syntaxhighlight>
and to tear down we can use AfterEach AfterAll
<syntaxhighlight lang="js">
afterAll(()=>{
  console.log("Hello");
});
</syntaxhighlight>
Note does not matter what order you write them in.
==Skipping and Isolating Tests==
Add keyword only to include tests
<syntaxhighlight lang="js">
it.only ("should display a list of items", ()=> {
    expect(2+2).toEqual(4);
})
</syntaxhighlight>
Add keyword skip to exlude tests
<syntaxhighlight lang="js">
it.skip ("should display a list of items", ()=> {
    expect(2+2).toEqual(4);
})
</syntaxhighlight>
=Async Tests=
<syntaxhighlight lang="js">
// Using a callback that is passed to the test force it to wait
it('async test 1', done=> {
    setTimeout(done, 100)
});
// Return a Promise which jest knows to wait for
it('async test 2',()=> {
    return new Promise(
        resolve => setTimeout(resolve,100)
    );
});
// Use await to wait before returning.
it('async test 1', async ()=>
    await delay(100)
);
</syntaxhighlight>
=Mocking=
==Why==
*Reduces dependencies and makes testing faster
*Prevents side effects
*Control the scenario we wish to test e.g. timeout, corrupt data
==What is Mocking==
A mock is a replacement for known functionality which can be used to capture usage of the original function and fake a response to the users of the mock.
==Setup==
Create directory __mocking__ at the same level as npm node_module you are trying to mock. This makes your module get loaded in place of the original module.
==Example==
===Function to Mock===
/**
* Fetch question details from the local proxy API
*/
<syntaxhighlight lang="javascript">
export function * handleFetchQuestion ({question_id}) {
    const raw = yield fetch(`/api/questions/${question_id}`);
    const json = yield raw.json();
    const question = json.items[0];
    /**
    * Notify application that question has been fetched
    */
    yield put({type:`FETCHED_QUESTION`,question});
}
</syntaxhighlight>
===Mocking the JavaScript Fetch function===
In the code below we are attempting to mock the javascript fetch function where call the function and return a value. I orginally struggled with this because of the old syntax but it became a lot clear after so much work with node js and modern javascript
<syntaxhighlight lang="javascript">
let __value = 42;
// Old syntax
// Replace a function which returns 42
const isomorphicFetch = jest.fn( (){ returns __value });
// Add a function to set the value
isomorphicFetch.__setValue = function(v) {__value = v};
// Modern notation
const isomorphicFetch = jest.fn( ()=> __value);
isomorphicFetch.__setValue = v => __value = v;
export default  isomorphicFetch;
</syntaxhighlight>
===Mocking the handleFetchQuestion===
Now we need to mock the original function above using our ownversion of fetch. We set the value to be the format expected back from fetch which is an object which we can do because __setValue is not type aware [{"question_id": 42}]
<syntaxhighlight lang="javascript">
import { handleFetchQuestion }  from './fetch-question-saga';
import fetch from 'isomorphic-fetch';
/**
* This test is an example of two important Jest testing principles,
* 1) we're mocking the "fetch" module, so that we don't actually make a request every time we run the test
*  The module, isomorphic fetch, is conveniently mocked automatically be including the file __mocks__/isomorphic-fetch.js adjacent to to the Node.js folder
* 2) we're using an async function to automatically deal with the fact that our app isn't synchronous
*/
describe("Fetch questions saga",()=>{
    beforeAll(()=>{
        fetch.__setValue([{question_id:42}]);
    });
    it("should get the questions from the correct endpoint in response to the appropriate action",async ()=>{
        const gen = handleFetchQuestion({question_id:42});
        /**
        * At this point, isomorphic fetch must have been mocked,
        * or an error will occur, or, worse, an unexpected side effect!
        */
        const { value } = await gen.next();
        expect(value).toEqual([{question_id:42}]);
        /**
        * We can also assert that fetch has been called with the values expected (note that we used a spy in the file where we mock fetch.)
        */
        expect(fetch).toHaveBeenCalledWith(`/api/questions/42`);
    });
});
</syntaxhighlight>
=Snapshot Testing=
It is really hard to be excited about this. It seems so fragile. Basically it records the first run and makes comparisons on subsequent runs. Any change is flagged.
<syntaxhighlight lang="javascript">
import React from 'react';
import TagsList from './TagsList'
import renderer from 'react-test-renderer';
describe("The tags list",()=>{
    /**
    * The tagsList can be tested against an expected snapshot value, as in below.
    */
  it ("renders as expected",()=>{
      const tree = renderer
          .create(<TagsList tags={[`css`,`html`,`typescript`,`coffeescript`]}/>)
          .toJSON();
      expect(tree).toMatchSnapshot();
  });
});
</syntaxhighlight>
=Component Testing=
See also [[React_Testing_Components]]
==Making Components More Testable==
From best to worse.
*No internal state - output is a idempotent product of the props
*No side-effects, have these handled by sagas, thunks etc
*No lifecycle hooks - fetching data handled on application level
==Component Testing with Redux==
===React and Redux===
These a perceived as a great match because it means
*Components do not generate side effects, only actions
*Components consist of display and container components
*No state in Components
So the approach to testing for React Redux Components is
*Test Container and Display Separately
*Use Unit test to verify methods and props on container
*Use snapshot tests for the display
===Redux and Testing mapStateToProps===
mapStateToProps is the function responsible for mapping state to the props. Our focus on testing here is only the mapping and not the content. i.e. that the state is appropriately mapped to the props.
<syntaxhighlight lang="javascript">
import { mapStateToProps } from '../QuestionDetail';
it("should map the state to props correctly", () => {
  // Sample App State with sampleQuestion being object in state
  const sampleQuestion {
      question_id:42,
      body: "Space is big"
  };
  const appState = {
      questions: [sampleQuestion]
  };
 
  // Sample Props
  const ownProps = {
      question:42
  });
  const componentState = mapStateToProps(appState, ownProps)
  expect(componentState).toEqual(sampleQuestion);
}
</syntaxhighlight>
==Component Testing with State==
Bit of a lot of code but here goes
===Create component===
<syntaxhighlight lang="javascript">
import React from 'react';
export default class extends React.Component {
    constructor)(...args) {
        super(...args);
        this.state = {
            count: -1
        }
    }
    async comonentDidMount () {
        let { count } = await NotificationService.GetNotification();
        this.setState( {
            count
        });
    }
    render() {
      return (
          <section className="mt-3 mb-2">
              <div className="notifications">
                  {this.state.count != -1
                  ? '${this.state.count} Notifications Awaiting!'
                  : 'Loading...'}
              </div>
          </section>
      )
    }
}
</syntaxhighlight>
===Create a Service===
<syntaxhighlight lang="javascript">
export default {
    async GetNoitifications() {
        console.warning("REAL NOTIFICATION SERVICE!");
        await delay(1000);
        return { count: 42 };
    }
}
</syntaxhighlight>
===Test Case===
And here is the test case
<syntaxhighlight lang="js">
import NotificationsViewer from '../NotificationsViewer';
import renderer from 'react-test-renderer';
import React from 'react';
import delay from 'redux-saga';
// NOTE Local module you need to pass in url of notification service
jest.mock('../../services/NotificationService');
// NOTE 2 this needs to be a require and needs to be after the jest. Making it
// an import will fail


=Example Test=
const notificationService = require('../../services/NotificationService').default;


Describe is the suite, it is the test
 
describe("The notification viewer", () => {
 
  beforeAll( ()=> {
    notificationService.__setCount(5);
  });
 
  it("should display the correct number of notifications", async()=> {
 
      const tree = renderer
          .create(
              <NoticationsViewer/>
            )
      await delay();
      const instance = tree.root;
 
      // find by className the component
      const component = instance.findByProps( { className: 'notificiations' }); 
 
      const text = component.children[0];
      export(text).toEqual("5 Notifications");


describe("The question list ", ()=> {
  });
    it ("should display a list of items", ()=> {
});
        expect(2+2).toEqual(4);
    })


    it ("should display a list of items", ()=> {
</syntaxhighlight>
        expect(2+4).toEqual(6);
===Mocked Service===
    })
Let's make a mocked service in the appropriate place next to the real service. src\services\__mocks__\NotificationService.js
<syntaxhighlight lang="js">
let count = 0;
export default {


})
    __setCount(__count) {
        count = _count;
    },
    async GetNotifications() {
        console.warn("Good Job! Using Mock");
    }
}
</syntaxhighlight>


=Setup and Teardown=
=Matchers in Jest=
These can be found [https://facebook.github.io/jest/docs/en/expect.html]


This can be done using
Some of them for quick reference.


  BeforeEach BeforeAll
  expect(value)
expect.extend(matchers)
expect.anything()
expect.any(constructor)
expect.arrayContaining(array)
expect.assertions(number)
expect.hasAssertions()
expect.not.arrayContaining(array)
expect.not.objectContaining(object)
expect.not.stringContaining(string)
expect.not.stringMatching(string | regexp)
expect.objectContaining(object)
expect.stringContaining(string)
expect.stringMatching(string | regexp)
expect.addSnapshotSerializer(serializer)
=Transpiling in Jest 2024=
I am certainly not expert but here is what I know. There several types of formats for modules,
*commonJS (uses require)
*esm (uses import)
==Introduction to issue==
When you run jest you may sometimes see<br>
[[File:Jest Error.png|600px]]<br>
This is because the module, in this case MsalReactTester, cannot be loaded because it is an esm module and you are running jest with commonJS.
==Solution==
To solve this problem we need to transpile (convert) the module from esm to commonJS. To do this we need to config jest like this.
<syntaxhighlight lang="js">


beforeAll(()=>{
export default async (): Promise<Config> => {
     console.log("Hello");
     return {
});
        rootDir: '../',


and
        verbose: true,
        setupFilesAfterEnv: ['<rootDir>/configs/setupTests.ts'],
        testEnvironment: '<rootDir>/configs/jest.environment.ts',


AfterEach AfterAll
        moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx'],
        moduleDirectories: ['node_modules', 'src'],
        moduleNameMapper: {
            '\\.(css|less|scss)$': 'identity-obj-proxy',
        },
        transform: {
            '^.+\\.(ts|tsx)?$': 'ts-jest',
            '^.+\\.(js|jsx)$': ['babel-jest', { configFile: './configs/babel.config.js' }],
            '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
                '<rootDir>/configs/__mocks__/fileMock.js',
            '^.+\\.(css|sass|scss)$': '<rootDir>/configs/__mocks__/styleMock.js',
        },


afterAll(()=>{
        testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'],
    console.log("Hello");
});


Note does not matter what order you write them in.
        transformIgnorePatterns: ['/node_modules/(?!(uint8array-extras|msal-react-tester)/)'],
...
}
</syntaxhighlight>
The important lines is the transformIgnorePatterns which tells jest to ignore all modules except uint8array-extras or msal-react-tester. I am hopeless at regex so went there to prove it. You can see only the last two are selected and therefore ignored.
[[File:Reg101 image1 jest.png | 400px]]


=Skipping and Isolating Tests=
==Other Configs==
There are other configurations involved too and are provided here for completeness
*setupTests.ts
*jest.environment.ts
<syntaxhighlight lang="ts">
// setupTests.ts
import '@testing-library/jest-dom'


Add keyword only to include tests
import crypto from 'crypto'
    it.only ("should display a list of items", ()=> {
        expect(2+2).toEqual(4);
    })


Add keyword only to include tests
Object.defineProperty(window, 'crypto', {
    it.only ("should display a list of items", ()=> {
    value: {
        expect(2+2).toEqual(4);
        randomUUID: () => crypto.randomUUID(),
    })
    },
})
</syntaxhighlight>
<br>
<syntaxhighlight lang="ts">
// jest.environment.ts
import Environment from 'jest-environment-jsdom'


Add keyword skip to exlude tests
export default class CustomTestEnvironment extends Environment {
    it.skip ("should display a list of items", ()=> {
    async setup() {
        expect(2+2).toEqual(4);
        await super.setup()
    })
        this.global.TextEncoder = TextEncoder
        this.global.TextDecoder = TextDecoder
        this.global.Response = Response
        this.global.Request = Request
    }
}
</syntaxhighlight>

Latest revision as of 05:22, 4 December 2024

Introduction

This is a page to introduce Jest. Facebook employs a lot of the people who develop jest and can be and is used for test in other frameworks.

Example code can be found at [here]

Choices

Popular tools for testing are Enzyme and Jasmine/Mocha. Jest is built on top of Jasmine/Mocha. Jest works with or without React and has a great assertion library.

Why Not Enzyme

This has over 200+ issues open and 26 of these are bugs. Jest is recommended by the react team.

Jest vs Mocha

Jest and Mocha both run tests sync and async but jest also has the following features.

  • Spies (stubbing methods to spy)
  • Snapshot testing
  • Module mocking (stubbing objects)

Getting Started

Running

We can run jest on it's own or continually with watch mode

jest --watch

At least one "it" block must be found or jest will return an error.

Code Coverage

With Jest we can get a report by typing

npm test  -- --coverage

Naming Test

The file names must be recognized as a test.

 __tests__/*.js
 *.spec.js
 *.test.js

Example Test in Jest

Describe is the suite, it is the test

describe("The question list ", ()=> {
    it ("should display a list of items", ()=> {
        expect(2+2).toEqual(4);
    })

    it ("should display a list of items", ()=> {
        expect(2+4).toEqual(6);
    })
})

Setup and Teardown

This can be done using before each and before all.

BeforeEach BeforeAll

beforeAll(()=>{
   console.log("Hello");
});

and to tear down we can use AfterEach AfterAll

afterAll(()=>{
   console.log("Hello");
});

Note does not matter what order you write them in.

Skipping and Isolating Tests

Add keyword only to include tests

it.only ("should display a list of items", ()=> {
    expect(2+2).toEqual(4);
})

Add keyword skip to exlude tests

it.skip ("should display a list of items", ()=> {
    expect(2+2).toEqual(4);
})

Async Tests

// Using a callback that is passed to the test force it to wait
it('async test 1', done=> {
    setTimeout(done, 100)
});

// Return a Promise which jest knows to wait for
it('async test 2',()=> {
    return new Promise(
        resolve => setTimeout(resolve,100)
    );
});

// Use await to wait before returning.
it('async test 1', async ()=>
    await delay(100)
);

Mocking

Why

  • Reduces dependencies and makes testing faster
  • Prevents side effects
  • Control the scenario we wish to test e.g. timeout, corrupt data

What is Mocking

A mock is a replacement for known functionality which can be used to capture usage of the original function and fake a response to the users of the mock.

Setup

Create directory __mocking__ at the same level as npm node_module you are trying to mock. This makes your module get loaded in place of the original module.

Example

Function to Mock

/**

* Fetch question details from the local proxy API
*/
export function * handleFetchQuestion ({question_id}) {
    const raw = yield fetch(`/api/questions/${question_id}`);
    const json = yield raw.json();
    const question = json.items[0];
    /**
     * Notify application that question has been fetched
     */
    yield put({type:`FETCHED_QUESTION`,question});
}

Mocking the JavaScript Fetch function

In the code below we are attempting to mock the javascript fetch function where call the function and return a value. I orginally struggled with this because of the old syntax but it became a lot clear after so much work with node js and modern javascript

let __value = 42;

// Old syntax

// Replace a function which returns 42
const isomorphicFetch = jest.fn( (){ returns __value });

// Add a function to set the value
isomorphicFetch.__setValue = function(v) {__value = v};

// Modern notation
const isomorphicFetch = jest.fn( ()=> __value);
isomorphicFetch.__setValue = v => __value = v;

export default  isomorphicFetch;

Mocking the handleFetchQuestion

Now we need to mock the original function above using our ownversion of fetch. We set the value to be the format expected back from fetch which is an object which we can do because __setValue is not type aware [{"question_id": 42}]

import { handleFetchQuestion }  from './fetch-question-saga';
import fetch from 'isomorphic-fetch';
/**
 * This test is an example of two important Jest testing principles,
 * 1) we're mocking the "fetch" module, so that we don't actually make a request every time we run the test
 *  The module, isomorphic fetch, is conveniently mocked automatically be including the file __mocks__/isomorphic-fetch.js adjacent to to the Node.js folder
 * 2) we're using an async function to automatically deal with the fact that our app isn't synchronous
 */
describe("Fetch questions saga",()=>{
    beforeAll(()=>{
        fetch.__setValue([{question_id:42}]);
    });
    it("should get the questions from the correct endpoint in response to the appropriate action",async ()=>{
        const gen = handleFetchQuestion({question_id:42});
        /**
         * At this point, isomorphic fetch must have been mocked,
         * or an error will occur, or, worse, an unexpected side effect!
         */
        const { value } = await gen.next();
        expect(value).toEqual([{question_id:42}]);

        /**
         * We can also assert that fetch has been called with the values expected (note that we used a spy in the file where we mock fetch.)
         */
        expect(fetch).toHaveBeenCalledWith(`/api/questions/42`);
    });
});

Snapshot Testing

It is really hard to be excited about this. It seems so fragile. Basically it records the first run and makes comparisons on subsequent runs. Any change is flagged.

import React from 'react';
import TagsList from './TagsList'
import renderer from 'react-test-renderer';


describe("The tags list",()=>{
    /**
     * The tagsList can be tested against an expected snapshot value, as in below.
     */
   it ("renders as expected",()=>{
       const tree = renderer
           .create(<TagsList tags={[`css`,`html`,`typescript`,`coffeescript`]}/>)
           .toJSON();

       expect(tree).toMatchSnapshot();
   });
});

Component Testing

See also React_Testing_Components

Making Components More Testable

From best to worse.

  • No internal state - output is a idempotent product of the props
  • No side-effects, have these handled by sagas, thunks etc
  • No lifecycle hooks - fetching data handled on application level

Component Testing with Redux

React and Redux

These a perceived as a great match because it means

  • Components do not generate side effects, only actions
  • Components consist of display and container components
  • No state in Components

So the approach to testing for React Redux Components is

  • Test Container and Display Separately
  • Use Unit test to verify methods and props on container
  • Use snapshot tests for the display

Redux and Testing mapStateToProps

mapStateToProps is the function responsible for mapping state to the props. Our focus on testing here is only the mapping and not the content. i.e. that the state is appropriately mapped to the props.

import { mapStateToProps } from '../QuestionDetail';

it("should map the state to props correctly", () => {

   // Sample App State with sampleQuestion being object in state
   const sampleQuestion {
       question_id:42,
       body: "Space is big"
   };

   const appState = {
       questions: [sampleQuestion]
   };
   
   // Sample Props
   const ownProps = {
       question:42
   });

   const componentState = mapStateToProps(appState, ownProps)
   expect(componentState).toEqual(sampleQuestion);
}

Component Testing with State

Bit of a lot of code but here goes

Create component

import React from 'react';

export default class extends React.Component {
    constructor)(...args) {
        super(...args);
        this.state = {
            count: -1
        }
    }

    async comonentDidMount () {
        let { count } = await NotificationService.GetNotification();
        this.setState( {
            count
        });
    }

    render() {
       return (
           <section className="mt-3 mb-2">
               <div className="notifications">
                   {this.state.count != -1 
                   ? '${this.state.count} Notifications Awaiting!' 
                   : 'Loading...'}
               </div>
           </section>
       )
    }
}

Create a Service

export default {
    async GetNoitifications() {
        console.warning("REAL NOTIFICATION SERVICE!");
        await delay(1000);
        return { count: 42 };
    }
}

Test Case

And here is the test case

import NotificationsViewer from '../NotificationsViewer';
import renderer from 'react-test-renderer';
import React from 'react';
import delay from 'redux-saga';

// NOTE Local module you need to pass in url of notification service
jest.mock('../../services/NotificationService');

// NOTE 2 this needs to be a require and needs to be after the jest. Making it
// an import will fail

const notificationService = require('../../services/NotificationService').default; 

  
describe("The notification viewer", () => {

   beforeAll( ()=> {
     notificationService.__setCount(5);
   });

   it("should display the correct number of notifications", async()=> {

       const tree = renderer
           .create(
               <NoticationsViewer/>
            )
       await delay();
       const instance = tree.root;

       // find by className the component
       const component = instance.findByProps( { className: 'notificiations' });  

       const text = component.children[0];
       export(text).toEqual("5 Notifications");

   });
});

Mocked Service

Let's make a mocked service in the appropriate place next to the real service. src\services\__mocks__\NotificationService.js

let count = 0;
export default {

    __setCount(__count) {
        count = _count;
    },
    async GetNotifications() {
        console.warn("Good Job! Using Mock");
    }
}

Matchers in Jest

These can be found [1]

Some of them for quick reference.

expect(value)
expect.extend(matchers)
expect.anything()
expect.any(constructor)
expect.arrayContaining(array)
expect.assertions(number)
expect.hasAssertions()
expect.not.arrayContaining(array)
expect.not.objectContaining(object)
expect.not.stringContaining(string)
expect.not.stringMatching(string | regexp)
expect.objectContaining(object)
expect.stringContaining(string)
expect.stringMatching(string | regexp)
expect.addSnapshotSerializer(serializer)

Transpiling in Jest 2024

I am certainly not expert but here is what I know. There several types of formats for modules,

  • commonJS (uses require)
  • esm (uses import)

Introduction to issue

When you run jest you may sometimes see

This is because the module, in this case MsalReactTester, cannot be loaded because it is an esm module and you are running jest with commonJS.

Solution

To solve this problem we need to transpile (convert) the module from esm to commonJS. To do this we need to config jest like this.

export default async (): Promise<Config> => {
    return {
        rootDir: '../',

        verbose: true,
        setupFilesAfterEnv: ['<rootDir>/configs/setupTests.ts'],
        testEnvironment: '<rootDir>/configs/jest.environment.ts',

        moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx'],
        moduleDirectories: ['node_modules', 'src'],
        moduleNameMapper: {
            '\\.(css|less|scss)$': 'identity-obj-proxy',
        },
        transform: {
            '^.+\\.(ts|tsx)?$': 'ts-jest',
            '^.+\\.(js|jsx)$': ['babel-jest', { configFile: './configs/babel.config.js' }],
            '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
                '<rootDir>/configs/__mocks__/fileMock.js',
            '^.+\\.(css|sass|scss)$': '<rootDir>/configs/__mocks__/styleMock.js',
        },

        testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'],

        transformIgnorePatterns: ['/node_modules/(?!(uint8array-extras|msal-react-tester)/)'],
...
}

The important lines is the transformIgnorePatterns which tells jest to ignore all modules except uint8array-extras or msal-react-tester. I am hopeless at regex so went there to prove it. You can see only the last two are selected and therefore ignored.

Other Configs

There are other configurations involved too and are provided here for completeness

  • setupTests.ts
  • jest.environment.ts
// setupTests.ts
import '@testing-library/jest-dom'

import crypto from 'crypto'

Object.defineProperty(window, 'crypto', {
    value: {
        randomUUID: () => crypto.randomUUID(),
    },
})


// jest.environment.ts
import Environment from 'jest-environment-jsdom'

export default class CustomTestEnvironment extends Environment {
    async setup() {
        await super.setup()
        this.global.TextEncoder = TextEncoder
        this.global.TextDecoder = TextDecoder
        this.global.Response = Response
        this.global.Request = Request
    }
}