DEV Community

Kinga
Kinga

Posted on • Updated on

Jest errors with solutions

You may find example SPFx solution on GitHub

1. Parsing error: "parserOptions.project"

Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
The file does not match your project config: test\components\HelloWorld.test.tsx.
The file must be included in at least one of the projects provided.
Enter fullscreen mode Exit fullscreen mode

Solution

Add .eslintignore file to the root of your project:

.eslintignore

.eslintrc.js

**/test/*.ts
**/test/*.tsx

*.test.ts
*.test.tsx
Enter fullscreen mode Exit fullscreen mode

2. Property 'toBeInTheDocument' does not exist...

error TS2339: Property 'toBeInTheDocument' does not exist on type 'JestMatchers<HTMLElement>'.
Enter fullscreen mode Exit fullscreen mode

Solution

Add import '@testing-library/jest-dom';

HelloWorld.test.tsx

import '@testing-library/jest-dom';
import { RenderResult, render } from '@testing-library/react';
import React from "react";
import HelloWorld from "../../src/webparts/helloWorld/components/HelloWorld";

describe("HelloWorld.tsx", () => {
    it("should render correctly", async () => {

        let helloWorld: RenderResult =  render(<HelloWorld  description="" isDarkTheme={false} environmentMessage="" hasTeamsContext={false} userDisplayName="" />);
        expect(helloWorld.getByTestId('helloWorld')).toBeInTheDocument();

    });
});
Enter fullscreen mode Exit fullscreen mode

3. Cannot read properties of undefined (reading 'createElement')

    TypeError: Cannot read properties of undefined (reading 'createElement')

       7 |     it("should render correctly", async () => {
       8 |
    >  9 |         let helloWorld: RenderResult =  render(<HelloWorld  description="" isDarkTheme={false} environmentMessage="" hasTeamsContext={false} userDisplayName="" />);
         |                                                ^
      10 |         expect(helloWorld.getByTestId('helloWorld')).toBeInTheDocument();
      11 |
      12 |     });
Enter fullscreen mode Exit fullscreen mode

Solution

Add "esModuleInterop": true, to compilerOptions in tsconfig.json

tsconfig.json

{
  "extends": "./node_modules/@microsoft/rush-stack-compiler-4.5/includes/tsconfig-web.json",
  "compilerOptions": {
    "target": "es5",
    "esModuleInterop": true,
    //...
}
Enter fullscreen mode Exit fullscreen mode

4. SyntaxError: Invalid or unexpected token

    Details:

C:\GitHub\Archive\spfx1.17.4_pnpm\src\webparts\helloWorld\components\HelloWorld.module.scss:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){@import '~@fluentui/react/dist/sass/References.scss';
                                                                                      ^
    SyntaxError: Invalid or unexpected token

      1 | import { escape } from '@microsoft/sp-lodash-subset';
      2 | import * as React from 'react';
    > 3 | import styles from './HelloWorld.module.scss';
Enter fullscreen mode Exit fullscreen mode

Solution

Add "\\.(css|scss)": "identity-obj-proxy" to moduleNameMapper in package.json

package.json

{
  //...
  "jest": {
    "moduleNameMapper": {
      "\\.(css|scss)": "identity-obj-proxy"
    }
}
Enter fullscreen mode Exit fullscreen mode

5. SyntaxError: Invalid or unexpected token


    Details:

    C:\GitHub\Archive\spfx1.17.4_pnpm\src\webparts\helloWorld\assets\welcome-light.png:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){PNG


    SyntaxError: Invalid or unexpected token

      18 |       <section className={`${styles.helloWorld} ${hasTeamsContext ? styles.teams : ''}`} data-testid="helloWorld" >
      19 |         <div className={styles.welcome}>
    > 20 |           <img alt="" src={isDarkTheme ? require('../assets/welcome-dark.png') : require('../assets/welcome-light.png')} className={styles.welcomeImage} />
Enter fullscreen mode Exit fullscreen mode

Solution

Media files aren't being mocked.

Create assetsTransformer.js in the root of your project.

assetsTransformer.js

const path = require('path');

module.exports = {
  process(src, filename, config, options) {
    return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
  },
};
Enter fullscreen mode Exit fullscreen mode

Add "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/assetsTransformer.js" to moduleNameMapper in package.json

package.json

{
  //...
  "jest": {
    "moduleNameMapper": {
      //...
      "\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)": "<rootDir>/assetsTransformer.js"
    }
}
Enter fullscreen mode Exit fullscreen mode

Credit where credit is due: github issue#2663

6. Cannot find module 'HelloWorldWebPartStrings' from 'src/webparts/helloWorld/components/HelloWorld.tsx'

Cannot find module 'HelloWorldWebPartStrings' from 'src/webparts/helloWorld/components/HelloWorld.tsx'

    Require stack:
      src/webparts/helloWorld/components/HelloWorld.tsx
      test/components/HelloWorld.test.tsx

      1 | import { escape } from '@microsoft/sp-lodash-subset';
    > 2 | import strings from 'HelloWorldWebPartStrings';
Enter fullscreen mode Exit fullscreen mode

Solution

Add "HelloWorldWebPartStrings": "<rootDir>/src/webparts/helloWorld/loc/myStrings.d.ts" to moduleNameMapper in package.json

package.json

{
  //...
  "jest": {
    "moduleNameMapper": {
      //...
      "HelloWorldWebPartStrings": "identity-obj-proxy"
    }
}
Enter fullscreen mode Exit fullscreen mode

And mock your strings as a constant:

HelloWorld.test.tsx

jest.mock('HelloWorldWebPartStrings', () => {
    return {
        PropertyPaneDescription: "Description",
        //...
    }
    { virtual: true }
})
Enter fullscreen mode Exit fullscreen mode

Source: surajit09's answer

7. The icon "info" was used but not registered.

This is just a warning you may see when testing react components using fluent ui icons. Annoying nevertheless.

Solution

In your test.tsx file add the following:

import { setIconOptions } from '@fluentui/react/lib/Styling';

// Suppress icon warnings.
setIconOptions({
  disableWarnings: true
});
Enter fullscreen mode Exit fullscreen mode

Source: Disabling warnings/test scenarios

You may find example SPFx solution on GitHub

8. Cannot use import statement outside a module

If you are getting errors similar to

 \node_modules\@pnp\azidjsclient\index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { PnPClientStorage, getHashCode } from "@pnp/core/index.js";
                                                                                      ^^^^^^
    SyntaxError: Cannot use import statement outside a module

      2 | import { DefaultAzureCredential } from "@azure/identity";
      3 | import { setLogLevel } from "@azure/logger";
    > 4 | import { AzureIdentity } from "@pnp/azidjsclient";
Enter fullscreen mode Exit fullscreen mode

you need to enable support for ECMAScript Modules (ESM), as described here

Solution

  1. On Windows, install cross-env: npm i cross-env --save-dev
  2. Update your test script in package.json. Replace "test": "jest" with "test": "cross-env NODE_OPTIONS=--experimental-vm-modules npx jest"
"scripts": {
  "test": "cross-env NODE_OPTIONS=--experimental-vm-modules npx jest"
},
Enter fullscreen mode Exit fullscreen mode

9. Must use import to load ES Module

After completing the step above, you may now see another error:

Err: Must use import to load ES Module: \node_modules\@pnp\azidjsclient\index.js

      2 | import { DefaultAzureCredential } from "@azure/identity";
      3 | import { setLogLevel } from "@azure/logger";
    > 4 | import { AzureIdentity } from "@pnp/azidjsclient";
Enter fullscreen mode Exit fullscreen mode

Solution

Add additional configuration to your package.json:

"jest": {
  "transform": {
    "^.+\\.(ts|tsx)?$": ["ts-jest", { "useESM": true }]
  },
  "extensionsToTreatAsEsm": [
    ".ts"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)