How can I test swiper with Jest?
Asked Answered
V

7

12

I'm creating unit testing of Swiper using Jest.

Here is my code:

https://codesandbox.io/s/swiper-default-react-forked-v0dnz?file=/src/App.test.jsx

● Test suite failed to run

    Cannot find module 'swiper/react' from 'src/App.jsx'

    Require stack:
      src/App.jsx
      src/App.test.jsx

      1 | import React from "react";
      2 | // Import Swiper React components
    > 3 | import { Swiper, SwiperSlide } from "swiper/react";
        | ^
      4 |
      5 | // Import Swiper styles
      6 | import "swiper/css";

      at Resolver.resolveModule (node_modules/jest-resolve/build/resolver.js:322:11)
      at Object.<anonymous> (src/App.jsx:3:1)

This error has been reported all the time, but the program can run normally. Can anyone help me solve this problem?

Viddah answered 20/9, 2021 at 5:20 Comment(3)
Swiper v7.0.0+ github.com/nolimits4web/swiper/issues/4871Viddah
Generally you can assume third party libraries are tested by authors so you don't need to it manuallyDive
@Mhmdrz_A yes, thanks, but my real page contains not only swiper, there are some other logi needs to be tested.Viddah
O
12

I suppose you are having issues with Swiper 7 or newer versions because Jest doesn't support ESM packages yet.

SOLUTION 1: For Swiper 7-9 or newer versions:

First add the swiper/css to jest's moduleNameMapper in package.json

  "jest": {
    "moduleNameMapper": {
      "swiper/css": "swiper/swiper.min.css"
    }
  }

Second, you can mock Swiper component to render its children:

jest.mock('swiper/react', () => ({
  Swiper: ({ children }) => <div data-testid="swiper-testid">{children}</div>,
  SwiperSlide: ({ children }) => (
    <div data-testid="swiper-slide-testid">{children}</div>
  ),
}))

In case you have also import any additional modules e.g:

  • For Swiper 7-9:
   // For Swiper 7-9
   import { Navigation, Pagination, Scrollbar, A11y } from 'swiper';
  • For Swiper 10-11 or newer versions:
   // For Swiper 10-11 or newer versions
   import { Navigation, Pagination, Scrollbar, A11y } from 'swiper/modules';

You can just mock the modules like this:

  • For Swiper 7-9:
  jest.mock('swiper', () => ({
    Navigation: (props) => null,
    Pagination: (props) => null,
    Scrollbar: (props) => null,
    A11y: (props) => null,
  }))
  • For Swiper 10-11 or newer versions:
  jest.mock('swiper/modules', () => ({
    Navigation: (props) => null,
    Pagination: (props) => null,
    Scrollbar: (props) => null,
    A11y: (props) => null,
  }))

Finally, as an example now you can write a test that checks how many slides rendered as a child of "swiper-slide-testid":

test('Renders component with 12 slides', () => {
  render(<Component/>)

  const slides = screen.getAllByTestId('swiper-slide-testid')
  expect(slides.length).toBe(12)
  
})

SOLUTION 2:

Even if it is not the most optimal solution, you can solve it by downgrading it to Swiper 6

Run these commands:

npm uninstall swiper
npm install [email protected]

And import it this way:

import { Swiper, SwiperSlide } from 'swiper/react'
import 'swiper/swiper-bundle.min.css'
import 'swiper/swiper.min.css'
Overwinter answered 12/1, 2022 at 16:57 Comment(0)
P
3

This seemed to work for me (Swiper v8):

(in package.json)

  "jest": {
    "moduleNameMapper": {
      "swiper/react": "swiper/react/swiper-react.js",
      "swiper/css": "swiper/swiper.min.css"
    },
    "transform": {
      "^.+\\.css$": "jest-transform-css"
    }
  }

(and maybe also add this to transformIgnorePatterns)

'node_modules/(?!(swiper|ssr-window|dom7)/)'
Pytlik answered 25/6, 2022 at 6:58 Comment(3)
If your imports are already set to the direct files, you don't need the moduleNameMapper. Also for my create-react app, I just needed the transformIgnorePatterns field set for swiper to work with jest.Doggone
Yep, but setting my imports to reference the direct file paths were giving me other errors (when running the app)Pytlik
transform and transformIgnorePatterns make it works for me, thank you.Membranous
C
1

If you don't care about testing Swiper v8 functionality, but want to test some other features in your components, try to add this line in your jest file:

jest.mock('Swiper', () => class Mocked {});

Worked for nextjs, doesn't complain. Maybe not the best way, but in my case it's more than enough.

Chally answered 21/9, 2022 at 13:28 Comment(0)
D
1

I'm using Swiper 8.4.2 and this worked for me while using Swiper in Jest.

TL;DR just give me the Jest config

Here is a configuration that worked for me.

/* eslint-disable */
export default {
  displayName: "components",
  preset: "../../jest.preset.js",
  moduleNameMapper: {
    // Jest cannot understand this swiper import so we tell it where this points to
    "swiper/css": "swiper/swiper.min.css",
  },
  transform: {
    "^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "@nrwl/react/plugins/jest",
    "^.+\\.[tj]sx?$": ["babel-jest", { presets: ["@nrwl/react/babel"] }],
  },
  moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
  coverageDirectory: "../../coverage/libs/components",
  setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
  transformIgnorePatterns: ["node_modules/(?!swiper|ssr-window|dom7)"],
};

Important things about config

Some of the things can be ignored because they are specific to this NX controlled monorepo, but couple of things are important here. So ignore "nrwl" and "nx" specifics, because I'm expecting this part about transformers to already be configured for your project whether you are using NX or something else.

What errors was I getting?

So running tests first threw errors "Jest encountered an unexpected token" and "SyntaxError: Unexpected token 'export'" for this line in my code:

import { Navigation } from "swiper";

Actual source of the error was this line in Swiper package:

export { default as Swiper, default } from './core/core.js';

Adding swiper|ssr-window|dom7 to transformIgnorePatterns resolved that issue.

Then after adding that I got the same error, but for this line:

import "swiper/css";

One of the answers above managed to help me with this actually because it involved "moduleNameMapper" property.

So adding this into the config solved the issue with this particular import:

  moduleNameMapper: {
    // Jest cannot understand this swiper import so we tell it where this points to
    "swiper/css": "swiper/swiper.min.css",
  },

Hopefully this helps someone with resolving their issue and actually understanding what parts of the config resolved specific issues.

Dag answered 28/12, 2022 at 16:57 Comment(0)
O
0

Who has mocking problem in version 10 of swiper, here is how you can solve it:

First, mock the swiper and the swiperSlide component

jest.mock('swiper/react', () => ({
  Swiper: ({ children }) => children,
  SwiperSlide: ({ children }) => children,
}));

Second, mock the modules of swiper (is new path compared to version 9)

jest.mock('swiper/modules', () => ({
  Navigation: props => null,
  Pagination: props => null,
  Scrollbar: props => null,
  A11y: props => null,
}));

Finnaly, mock swiper css

jest.mock('swiper/css', () => jest.fn());
Outset answered 3/8, 2023 at 14:40 Comment(0)
A
0

I used the version 10.x.x and none of the solutions above worked.

Then I downgraded to version 9.4.1, the last 9.x.x version.

Added this line to package.json (or your jest config file) as suggested in this thread => https://github.com/nolimits4web/swiper/discussions/4969#discussioncomment-1803613

 "jest": {
    "transformIgnorePatterns": [
      "/node_modules/(?!swiper|ssr-window|dom7)"
    ]
  }

And change the import statement of swiper css

from

import "swiper/css";

to

import "swiper/swiper.min.css"; 

Then it worked. The thread link above has rich discussion about how to solve it, so if this does not work in your side, I suggest to read it carefully and you might find your own workaround.

Ascend answered 25/9, 2023 at 20:11 Comment(0)
H
0

Works for "swiper": "^11.0.5".

package.json:

"jest": {
    "moduleNameMapper": {
      "swiper/react": "swiper/swiper-react.d.ts",
      "swiper/modules": "swiper/types/modules/index.d.ts",
      "swiper/css": "swiper/swiper.min.css"
    } 
}

Swiper.test.tsx:

jest.mock('swiper/react', () => ({
  Swiper: ({ children }: any) => children,
  SwiperSlide: ({ children }: any) => children,
}));

jest.mock('swiper/modules', () => ({
  Navigation: jest.fn(),
  Pagination: jest.fn(),
}));
Heavyset answered 25/1 at 11:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.