asmyshlyaev177 / react-horizontal-scrolling-menu

Horizontal scrolling menu component for React.
https://www.npmjs.com/package/react-horizontal-scrolling-menu
MIT License
768 stars 98 forks source link

[BUG] Cannot be imported in Jest with Next.js #240

Closed xian0831 closed 1 year ago

xian0831 commented 1 year ago

Describe the bug

@asmyshlyaev177 Thanks for building this library. I would like to report an issue I'm facing related to testing components that leverage the react-horizontal-scrolling-menu. I'm able to build the app fine, it is just not working with Jest unit test.

To Reproduce There is not issue when using the library so there is nothing to reproduce.

I suspect the issue might have something to do with the Jest transform.This is the config I have.

    // A map from regular expressions to paths to transformers
    transform: {
        '^.+\\.(t|j)sx?$': [
            'babel-jest',
            {
                presets: ['next/babel'],
                plugins: [
                    'dynamic-import-node',
                    [
                        'babel-plugin-styled-components',
                        {
                            displayName: true,
                            preprocess: false,
                            fileName: false,
                        },
                    ],
                ],
            },
        ],
        '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2|svg)$':
            'jest-transform-stub',
    },

When I run the test, this is what I get SyntaxError: Cannot use import statement outside a module

image

Expected behavior Successfully rendering by Jest using jsdom

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Additional context Someone else had anther import issue. I suspect it is somewhat related to this issue. However, I can't confirm that. Again, thanks for building the library.

AlexSmyshlyaev-sm commented 1 year ago

Hi, better try to google it, seems like it's common problem with NextJs. https://dev.to/steveruizok/jest-and-esm-cannot-use-import-statement-outside-a-module-4mmj https://github.com/ant-design/pro-components/issues/6525 https://stackoverflow.com/questions/70916761/next-js-and-jest-syntaxerror-cannot-use-import-statement-outside-a-module https://stackoverflow.com/questions/66244968/cannot-use-import-statement-outside-a-module-error-when-importing-react-hook-m https://www.google.com/search?q=nextjs+jest+cannot+use+import+statement+outside+a+module

I'm planning to update Nextjs and test with it, but not right now.

andrey-shostik commented 1 year ago

@xian0831 Have you fixed this issue?

andrey-shostik commented 1 year ago

I have resolved the issue. Just add to jest.config.js

  moduleNameMapper: {
    '^react-horizontal-scrolling-menu$': 'react-horizontal-scrolling-menu/dist/index.cjs',
  },
xian0831 commented 1 year ago

@andrey-shostik Sorry for getting back on this super late. I'm still having issue with your approach. However, if I switch from babel-jest to ts-jest. It solve the issue for this package, but other packages will failed for the same SyntaxError: Cannot use import statement outside a module error. Do you use ts-jest?

andrey-shostik commented 1 year ago

@xian0831 No, I don't use ts-jest Babelrc

  const presets = [
    '@babel/preset-env',
    isTestEnv && 'next/babel', // Note: Ships with babel-plugin-transform-react-remove-prop-types
  ].filter(Boolean);
const plugins = [
      'module-resolver',
      {
        root: ['./'],
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
      },
    ],
  ];
asmyshlyaev177 commented 9 months ago

I tested it with NextJs v14.0.1. This is really messed up, it depends on NextJS version, library, your setup and phase of the moon. I don't recommend testing complex browser related behavior with Jest, use Cypress or Playwright for that. Because jsdom lack browsers APIs(like IntersectionObjerver), and you will end up testing Jest mocks and not your code.

Steps:

1. Install testing library and deps npm i -D @testing-library/jest-dom @testing-library/react @testing-library/user-event jest-environment-jsdom

2. Create jest.config.ts file with

import type { Config } from 'jest'
import nextJest from 'next/jest.js'

const createJestConfig = nextJest({
  dir: './',
})

const config: Config = {
  coverageProvider: 'v8',
  // NOTE: important
  testEnvironment: 'jest-environment-jsdom', // or 'jsdom'
  setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
}

export default createJestConfig(config)

3. Create jest.setup.js file with:

import '@testing-library/jest-dom'

// // NOTE: Mock IntersectionObserver
class IntersectionObserver {
  observe = jest.fn()
  disconnect = jest.fn()
  unobserve = jest.fn()
}

Object.defineProperty(window, 'IntersectionObserver', {
  writable: true,
  configurable: true,
  value: IntersectionObserver,
})

Object.defineProperty(global, 'IntersectionObserver', {
  writable: true,
  configurable: true,
  value: IntersectionObserver,
})

5. Create test file:

import React from 'react'
import { render } from '@testing-library/react';

import { App } from './page'

describe("Smoke test", () => {
  test('should render without errors', () => {
    const {  container } = render(<App />)

    expect(container).toBeTruthy()
  })
})

6. Add test script to package.json: "test": "jest", and run it npm run test

kkorach commented 3 weeks ago

I was able to get past this error by updating my jest.config.js with these values:

 moduleNameMapper: {
    '^react-horizontal-scrolling-menu$': '<rootDir>/node_modules/react-horizontal-scrolling-menu/dist/index.cjs',
  },
asmyshlyaev177 commented 3 weeks ago

I was able to get past this error by updating my jest.config.js with these values:

 moduleNameMapper: {
    '^react-horizontal-scrolling-menu$': '<rootDir>/node_modules/react-horizontal-scrolling-menu/dist/index.cjs',
  },

Jest can be tricky, recently I just switched to Vitest because had too many issues with it.