Jest SyntaxError: Unexpected token < - reactjs

I'm want to test a component in a React app using Jest Enzyme with TypeScript. I follow the instructions on the Jest site, but for some reason I get:
SyntaxError: Unexpected token <
I can test test some functions. There isn't any problem with that, but when I use a component, I get an error.
This is the Jest configuration in file package.json:
"jest": {
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"testMatch": ["**/__tests__/*.(ts|tsx)"],
"snapshotSerializers": ["enzyme-to-json/serializer"],
"setupFilesAfterEnv": ["<rootDir>/src/setupEnzyme.ts"],
"unmockedModulePathPatterns": ["node_modules/react/", "node_modules/enzyme/"]
}
Enzyme configuration
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
export default class TesComponent extends Component {
render(){
return (
<div>test</div>
)
}
}
import { shallow } from 'enzyme'
import TestCompoenent from '../TestComponent'
test('component testing', () => {
const component = shallow(<TestCompoenent />)
expect(component.contains(<div>test</div>)).toBeTruthy()
})
This is the error:
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g., it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/home/user/Documents/local-platform/frontend/src/pages/__tests__/settigs.test.tsx:9
var component = enzyme_1.shallow(<TestComponent_1.default />);
^
SyntaxError: Unexpected token <
at ScriptTransformer._transformAndBuildScript (node_modules/#jest/transform/build/ScriptTransformer.js:471:17)
at ScriptTransformer.transform (node_modules/#jest/transform/build/ScriptTransformer.js:513:25)
I expect for the tests to pass, because Test Component does include <div>test</div>.

Try changing tsconfig.json
"jsx": "preserve" -> "jsx": "react"

It seems that your configuration does not process the TypeScript file (.tsx) properly.
Here is part of my working configuration:
"jest": {
"transform": {
"^.+\\.tsx?$": "ts-jest",
},
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"json"
],
"setupTestFrameworkScriptFile": "<rootDir>/src/setupSpecs.ts"
}
I have used setupTestFrameworkScriptFile instead of setupFilesAfterEnv.

Related

Jest to vitest migration error; equivalent of moduleNameMapper

I am trying to migrate from jest to vitest.
at some point I get this error :
Syntax Error: Invalid or unexpected token
It seems one of the packages we have in project has this line that causes the issue:
require("./lib/somefont.woff")
I checked jest and jest has this line which resolved the issue:
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less|scss|sass)$": "identity-obj-proxy"
},
I was wondering how I can resolve the issue in vitest?
is there an equivalent of moduleNameMapper in vitest?
Use import to import the font
import "./lib/somefont.woff"
Try setting alias config in vitest.config.js
import { defineConfig } from 'vite'
export default defineConfig({
test: {
globals: true,
environment: "jsdom",
alias: {
".*\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
},
},
});

React Testing library custom setup import test-utils: module not installed. Unable to resolve path

I'm trying to configure jest absolute path for my custom test-utils directory (https://testing-library.com/docs/react-testing-library/setup#configuring-jest-with-test-utils), but I get the error Cannot find module 'test-utils' / unable to resolve path
My folder tree
-src/
--utils/
---test-utils/
----test-utils.js
----custom-queries.js
-jest.config.js
-jsconfig.json
My jest.config.js
module.exports = {
transform: {
'^.+\\.jsx?$': 'babel-jest',
},
testEnvironment: 'jsdom',
moduleNameMapper: {
'\\.(css|less)$': 'identity-obj-proxy',
},
moduleDirectories: [
'node_modules',
'src',
'utils',
'test-utils',
],
};
My jsconfig.json
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"test-utils": ["./utils/test-utils"]
}
},
"include": ["src"],
"exclude": ["node_modules"]
}
My component test
import { render } from 'test-utils';
import React from 'react';
import '#testing-library/jest-dom/extend-expect';
import Alert from './alert';
describe('Alert', () => {
test('Renders Alert component', () => {
const { getByRole } = render(<Alert message="Success!" />);
const alert = getByRole(/alert/);
expect(alert).toHaveTextContent('Success!');
});
});
The test-utils is your custom module for which you specify path alias and how to resolve it in jsconfig.json as follows:
"compilerOptions":{
"baseUrl":"src",
"paths":{
"test-utils": ["./utils/test-utils"]
}
}
The same way you need to tell to Jest how to resolve it with moduleNameMapper option in your jest.config.js as follows:
moduleNameMapper: {
'test-utils/(.*)": "<rootDir>/src/utils/test-utils/$1',
},
For official documentation see: https://jestjs.io/docs/configuration#modulenamemapper-objectstring-string--arraystring
For similar issues see: Jest not finding alias path, React: Jest configuration Issue with Path Aliases and How to use path alias in a react project with Typescript + Jest

Trying to test using jest but running into issues

Im trying to test a component using jest. The component imports spacetime npm module, which uses es-modules on main
https://www.npmjs.com/package/spacetime
I'm running into the following issues:
● Test suite failed to run
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
• If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation
Details:
/Users/wscott/dev/pm/client/node_modules/spacetime/src/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import Spacetime from './spacetime.js'
^^^^^^
SyntaxError: Cannot use import statement outside a module
6 | import search from '../../assets/images/search.svg';
7 | import Dropdown from 'react-bootstrap/Dropdown';
> 8 | import spacetime from "spacetime";
| ^
9 | import languages from "../../libraries/languages/language-list";
10 | import { Rating } from 'react-simple-star-rating';
11 |
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1728:14)
at Object.<anonymous> (src/components/Mentor/MentorList.js:8:1)
Here's my jest.config.js file
module.exports = {
preset: 'ts-jest',
transform: {
'^.+\\.(ts|tsx)?$': 'ts-jest',
"^.+\\.(js|jsx)$": "babel-jest",
".+\\.(css|styl|less|sass|scss)$": "jest-transform-css"
},
"moduleNameMapper": {
"\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/__mocks__/fileMock.js",
"\\.(css|less)$": "<rootDir>/src//__mocks__/fileMock.js"
},
"setupFiles":["./src/browserMocks.js"],
"globals": {
"window": {
location: {
href: ""
},
localStorage: {
getItem: () => {
}
}
},
"localStorage": {
getItem: () => {
}
}
}
};
Here's my babel.config.js file:
module.exports = {
presets:[
"#babel/preset-env",
"#babel/preset-react"
],
"env": {
"test": {
"plugins": ["#babel/plugin-transform-modules-commonjs"]
}
}
}
Can someone help?
Downgrading to 6.12.3 fixes the issue with jest. The issue is space time use es-module imports which jest doesn't support but downgrading should work
Try to set the transformIgnorePatterns property to let jest transform the file before tests:
transformIgnorePatterns: [
'node_modules/(?!(spacetime)/)',
],
This way you are telling to skip transformation for all your node_modules except spacetime, which will be transformed by babel-jest as is set in you configuration.

getting jest to work with babel / laravel-mix

I'm using jest and testing-library/react for tests of my ReactJS components in a Laravel app.
My tests break because the component to to test isn't recognised by jest even after importing it into the test. I have the following settings in jest.config.js
module.exports = {
testRegex: 'resources/js/tests/.*.test.js$',
roots: ["<rootDir>/resources/js/"],
moduleDirectories: ["resources/js/components", "resources/js/containers", "resources/js/views", "node_modules"]
}
And in the package.json file
"test": "cross-env NODE_ENV=test jest",
Here's a simple test that fails due to error
import React from "react";
import { render, fireEvent, waitForElement } from "#testing-library/react";
import "#testing-library/jest-dom/extend-expect";
import axiosMock from "axios";
// the component to test
import BlogEditor from "../../components/BlogEditor/BlogEditor";
jest.mock("axios");
test("Blog Editor recieves props and renders", () => {
const { getByTestId } = render(
<BlogEditor
tags={[{ id: 1, name: "A tag"}]}
suggestions={[{id: 2, name: "A Suggestion"}]}
/>
);
});
The error I get is rather cryptic
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
SyntaxError: /Users/anadi/Code/adminpanel/resources/js/tests/BlogEditor/BlogEditor.test.js: Unexpected token (16:8)
14 | test("Blog Editor recived props and renders element", () => {
15 | const { getByTestId } = render(
> 16 | <BlogEditor
| ^
17 | tags={[{ id: 1, name: "A tag"}]}
18 | suggestions={[{id: 2, name: "A Suggestion"}]}
19 | />
at Parser.raise (node_modules/#babel/parser/src/parser/location.js:41:63)
at Parser.unexpected (node_modules/#babel/parser/src/parser/util.js:150:16)
at Parser.parseExprAtom (node_modules/#babel/parser/src/parser/expression.js:1123:20)
at Parser.parseExprSubscripts (node_modules/#babel/parser/src/parser/expression.js:529:23)
at Parser.parseMaybeUnary (node_modules/#babel/parser/src/parser/expression.js:509:21)
at Parser.parseExprOps (node_modules/#babel/parser/src/parser/expression.js:279:23)
at Parser.parseMaybeConditional (node_modules/#babel/parser/src/parser/expression.js:234:23)
at Parser.parseMaybeAssign (node_modules/#babel/parser/src/parser/expression.js:185:21)
at Parser.parseExprListItem (node_modules/#babel/parser/src/parser/expression.js:2077:18)
at Parser.parseCallExpressionArguments (node_modules/#babel/parser/src/parser/expression.js:817:14)
The problem was with my babel and jest configurations, moved jest configuration to package.json (I have no clue why this actually helped) but it did
"jest": {
"verbose": true,
"clearMocks": true,
"collectCoverage": true,
"testRegex" : "resources/js/tests/.*.test.js$",
"roots": ["<rootDir>/resources/js/"],
"moduleDirectories": ["resources/js/components", "resources/js/containers", "resources/js/views", "node_modules"],
"transform": {
"^.+\\.js$": "babel-jest"
},
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/resources/js/__mocks__/fileMock.js",
"\\.(css|scss)$": "<rootDir>/resources/js/__mocks__/styleMock.js"
}
and updated the babel configuration too
{
"presets": [
"#babel/preset-env",
"#babel/preset-react"
],
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-syntax-dynamic-import"
]
}

Jest throws error Unexpected token function when trying to import component

I am trying to test a basic react component with Jest, but it breaks when I try to import the component. EDIT: Noticed that it doesnt throw this error if I load in a more simple component. The one I am trying to load in is basically the same but has an async instance method. Perhaps that is what is breaking jest?
test.js
import React from 'react';
import {shallow} from 'enzyme';
import Component from '../components/component';
describe('Component', () => {
it('renders the player component', () => {
expect(true).toBe(true)
});
});
.babelrc
{
"presets": ["es2015", "react"]
}
package.json jest config:
"jest": {
"setupTestFrameworkScriptFile": "./node_modules/jest-enzyme/lib/index.js",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"json",
"jsx"
],
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react",
"<rootDir>/node_modules/react-dom",
"<rootDir>/node_modules/react-addons-test-utils"
]
}
You are probably right in your assumption about the async keyword breaking the test. If you are running this tests in a lower version of NodeJS than v7.6, async / await is not supported by the presets you are using in the .babelrc file.
You need one of these presets / plugins:
https://babeljs.io/docs/plugins/transform-async-to-generator/
https://github.com/babel/babel-preset-env with the correct settings
https://babeljs.io/docs/plugins/preset-es2017/

Resources