I'm learning to test React projects using RTL and Jest from one of the Udemy courses. The instructor provides a pure React project. In the video, the test is passing for the instructor but the same code is failing for me and Jest is throwing the error "SyntaxError: Cannot use import statement outside a module".
I researched on google and tried few solutions like transformIgnorePatterns: [/node_modules/(?!axios)
], adding "type": "module" in package.json, and mock axios using Jest but none of them worked for me.
package.json
{
"name": "codesplain",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:8000",
"dependencies": {
"@exuanbo/file-icons-js": "^3.3.0",
"@monaco-editor/react": "^4.4.6",
"@playwright/test": "^1.28.1",
"@primer/octicons-react": "^17.9.0",
"@prisma/client": "^4.7.0",
"@tailwindcss/forms": "^0.5.3",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.6.7",
"classnames": "^2.3.2",
"concurrently": "^7.6.0",
"cookie-session": "^2.0.0",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"msw": "^0.49.2",
"nodemon": "^3.0.3",
"playwright": "^1.28.1",
"prisma": "^4.7.0",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router": "^6.4.4",
"react-router-dom": "^6.4.4",
"react-scripts": "^5.0.1",
"react-split": "^2.0.14",
"swr": "^2.0.0",
"validate.js": "^0.13.1",
"web-vitals": "^2.1.4"
},
"prisma": {
"schema": "server/prisma/schema.prisma"
},
"scripts": {
"start": "concurrently \"npm:start:server\" \"npm:start:client\"",
"start:client": "react-scripts start",
"start:server": "nodemon --watch server server/index.mjs",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"autoprefixer": "^10.4.13",
"postcss": "^8.4.19",
"tailwindcss": "^3.2.4"
}
}
Test File With Mock Axios With Jest
import { render, screen } from "@testing-library/react";
import { setupServer } from "msw/node";
import { rest } from "msw";
import { MemoryRouter } from "react-router-dom";
import HomeRoute from "./HomeRoute";
import axios from "axios";
jest.mock("axios");
const mockedAxios = axios;
const handlers = [
mockedAxios.get("/api/repositories", (req, res, ctx) => {
const language = req.url.searchParams.get("q").split("language:")[1];
return res(
ctx.json({
items: [
{ id: 1, full_name: `${language}_one` },
{ id: 2, full_name: `${language}_two` },
],
})
);
}),
];
const server = setupServer(...handlers);
beforeAll(() => {
server.listen();
});
afterEach(() => {
server.resetHandlers();
});
afterAll(() => {
server.close();
});
test("renders two links for each language", async () => {
render(
<MemoryRouter>
<HomeRoute />
</MemoryRouter>
);
const languages = [
"javascript",
"typescript",
];
for (let language of languages) {
const links = await screen.findAllByRole("link", {
name: new RegExp(`${language}_`),
});
expect(links).toHaveLength(2);
}
});
Test File Without Mock As Per The Course Video
import { render, screen } from "@testing-library/react";
import { setupServer } from "msw/node";
import { rest } from "msw";
import { MemoryRouter } from "react-router-dom";
import HomeRoute from "./HomeRoute";
const handlers = [
rest.get("/api/repositories", (req, res, ctx) => {
const language = req.url.searchParams.get("q").split("language:")[1];
return res(
ctx.json({
items: [
{ id: 1, full_name: `${language}_one` },
{ id: 2, full_name: `${language}_two` },
],
})
);
}),
];
const server = setupServer(...handlers);
beforeAll(() => {
server.listen();
});
afterEach(() => {
server.resetHandlers();
});
afterAll(() => {
server.close();
});
test("renders two links for each language", async () => {
render(
<MemoryRouter>
<HomeRoute />
</MemoryRouter>
);
const languages = [
"javascript",
"typescript",
];
for (let language of languages) {
const links = await screen.findAllByRole("link", {
name: new RegExp(`${language}_`),
});
expect(links).toHaveLength(2);
}
});
Any suggestion on how to fix this error?
If you have a look in node_modules/axios you may check index.js file and see:
import axios from './lib/axios.js';
and this causes that issue, node would not recognize that import syntax.
Try to use that - https://github.com/axios/axios/issues/5101#issuecomment-1296024311. That will force jest to import version of axios which is compatible with node.js instead.
UPD: also have a look - https://stackoverflow.com/a/74297004/19742146
UPD: as you use Jest 27 version also have a look - https://jestjs.io/blog/2022/04/25/jest-28#packagejson-exports Jest 28 supports now exports field and probably it may solves your issue without any jest configs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With