I'm new to React Testing Library and Jest. I could successfully run a simple set of tests on it, like the below,
but when I tried to test on my "App.js", where a lot of imports/requires, it started to get a many set of errors on the each import, and I'm tbh overwhelmed.
Here's a working example:
./src/dev/test/AppTmp.js
import React from "react";
export const Topbar = () => {
return (
<>
<p>hoge.</p>
</>
)
}
./src/__tests__/hello.js
import '#testing-library/jest-dom/extend-expect'
import React from 'react'
import { render, screen } from '#testing-library/react'
import * as renderer from "react-test-renderer";
import { Topbar } from '../dev/test/AppTmp'
test('tmp test.', () => {
const component = renderer.create(
<Topbar />,
);
let tree = component.toJSON();
expect(tree).toMatchSnapshot();
})
The above successfully runs.
A problem is when I add an import line like this:
./src/dev/test/AppTmp.js
import React from "react";
import ReactMarkdown from 'react-markdown'; // <--- added this
export const Topbar = () => {
return (
<>
<p>hoge.</p>
</>
)
}
./src/__tests__/hello.js
import '#testing-library/jest-dom/extend-expect'
import React from 'react'
import { render, screen } from '#testing-library/react'
import * as renderer from "react-test-renderer";
import { Topbar } from '../dev/test/AppTmp'
test('tmp test.', () => {
const component = renderer.create(
<Topbar />,
);
let tree = component.toJSON();
expect(tree).toMatchSnapshot();
})
The above, with just an extra import line, causes the following error:
● 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.
...
...
Details:
/home/user/pg/react/myapp/node_modules/react-markdown/index.js:6
export {uriTransformer} from './lib/uri-transformer.js'
^^^^^^
SyntaxError: Unexpected token 'export'
24 | import "prismjs/themes/prism-tomorrow.css";
25 | import { LoremIpsum } from "react-lorem-ipsum";
> 26 | import ReactMarkdown from 'react-markdown';
| ^
27 |
28 | export const Topbar = () => {
29 | return (
at Runtime.createScriptFromCode (../node_modules/jest-runtime/build/index.js:1796:14)
at Object.<anonymous> (dev/test/AppTmp.js:26:1)
Test Suites: 1 failed, 2 passed, 3 total
(note: actually I had more lines as showing above, but what I'm doing is essentially the same, so kindly ignore them)
So this is an SyntaxError: Unexpected token 'export' error. Well, At first I thought I'm going to solve the error on SO or Google. But the error hell continues...
Now I added a different line as the following.
./src/dev/test/AppTmp.js
import React from "react";
// import ReactMarkdown from 'react-markdown';
import Slider from "react-slick"; // <--- added this
export const Topbar = () => {
return (
<>
<p>hoge.</p>
</>
)
}
The above caused an error:
● Test suite failed to run
matchMedia not present, legacy browsers require a polyfill
25 | import { LoremIpsum } from "react-lorem-ipsum";
26 | // import ReactMarkdown from 'react-markdown';
> 27 | import Slider from "react-slick";
| ^
28 | import "slick-carousel/slick/slick.css";
29 | import "slick-carousel/slick/slick-theme.css";
30 | import 'bootstrap';
at new MediaQueryDispatch (../node_modules/enquire.js/src/MediaQueryDispatch.js:15:15)
at Object.<anonymous> (../node_modules/enquire.js/src/index.js:2:18)
at Object.<anonymous> (../node_modules/react-slick/lib/slider.js:50:53)
at Object.<anonymous> (../node_modules/react-slick/lib/index.js:8:38)
at Object.<anonymous> (dev/test/AppTmp.js:27:1)
at Object.<anonymous> (__tests__/hello.js:8:1)
Test Suites: 1 failed, 2 passed, 3 total
This time I got an matchMedia not present, legacy browsers require a polyfill error.
Error hell continues. Next I tried:
./src/dev/test/AppTmp.js
import React from "react";
// import ReactMarkdown from 'react-markdown';
// import Slider from "react-slick";
import { nanoid } from 'nanoid'; // <--- added this
export const Topbar = () => {
return (
<>
<p>hoge.</p>
</>
)
}
● 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.
...
...
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:
/home/user/pg/react/myapp/node_modules/nanoid/index.browser.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { urlAlphabet } from './url-alphabet/index.js'
^^^^^^
SyntaxError: Cannot use import statement outside a module
49 | // import uniqueId from 'lodash/utility/uniqueId'
50 | import _ from 'lodash'
> 51 | import { nanoid } from 'nanoid';
| ^
52 | import { WithContext as ReactTags } from 'react-tag-input';
53 |
54 | const mymodules = require("./../../mymodules.js")
at Runtime.createScriptFromCode (../node_modules/jest-runtime/build/index.js:1796:14)
at Object.<anonymous> (dev/test/AppTmp.js:51:1)
Test Suites: 1 failed, 2 passed, 3 total
This time, got an error SyntaxError: Cannot use import statement outside a module. What the hell is going on.....
./.babelrc
{
"presets": [
[
"#babel/preset-env",
{
"loose": true,
"modules": false,
"targets": {
"browsers": "last 2 chrome versions"
}
}
],
"#babel/preset-react"
],
"plugins": [
"react-hot-loader/babel",
["#babel/plugin-proposal-class-properties", { "loose": true }]
],
"env": {
"test": {
"presets": [
[
"#babel/preset-env",
{
"loose": true,
"modules": false
}
],
"#babel/preset-react"
],
"plugins": [
"#babel/plugin-transform-runtime",
"#babel/plugin-transform-modules-commonjs"
]
}
}
}
./package.json
"jest": {
"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)$": "<rootDir>/__mocks__/styleMock.js"
},
"transform": {
"\\.[jt]sx?$": "babel-jest"
},
"moduleFileExtensions": [
"js",
"jsx",
"tsx"
],
"moduleDirectories": [
"node_modules"
],
"rootDir": "src",
"transformIgnorePatterns": [
"/node_modules/(?![#autofiy/autofiyable|#autofiy/property]).+\\.js$",
"/node_modules/(?![#autofiy/autofiyable|#autofiy/property]).+\\.ts$",
"/node_modules/(?![#autofiy/autofiyable|#autofiy/property]).+\\.tsx$",
"/node_modules/(?!my-package)(.*)",
"/node_modules/(?!#ngrx|(?!deck.gl)|ng-dynamic)"
],
"testEnvironment": "jsdom"
},
So, what's the best thing I can do now?
actually I've been taking 8 hours so far on Jest to get the above-mentioned simple example working, I didn't expect just a testing development environment building is this damn hard way.
I mean I think I'm doing something fundamentally wrong. that's why I'm getting this many errors no? What's not right with this setup, can I ask a help? Thanks.
Related
I have a react native app that I am trying to run tests on, I have set up a basic greeting component as shown below called Greetings.js:
import React from 'react';
import {View, Text} from 'react-native';
const Greetings = ({hello}) => {
return (
<View>
<Text>{hello}</Text>
</View>
);
};
export default Greetings;
This is the test I am running called Greetings.test.js:
import React from 'react';
import {render, screen} from '#testing-library/react-native';
import Greetings from './Greetings';
describe('Greetings component', () => {
it('renders hello world as a test', () => {
render(<Greetings hello="Hello World!" />);
const helloWorldElement = screen.getByText('Hello World!');
expect(helloWorldElement).toBeInTheDocument();
});
});
For some reason it doesnt recognise the react native components, this is the error when running the test:
FAIL app/__tests__/components/Account/Greetings.test.js
● Console
console.error
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You li
forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `Greetings`.
at Greetings (C:\Users\meeve\OneDrive\Desktop\Cozify\smartliving-app\app\__tests__\components\Account\Greetings.js:4:21)
5 | return (
6 | <View>
> 7 | <Text>{hello}</Text>
| ^
8 | </View>
9 | );
10 | };
at printWarning (node_modules/react/cjs/react.development.js:220:30)
at error (node_modules/react/cjs/react.development.js:196:5)
at Object.createElementWithValidation [as createElement] (node_modules/react/cjs/react.development.js:2215:7)
at Greetings (app/__tests__/components/Account/Greetings.js:7:7)
at renderWithHooks (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6016:18)
at mountIndeterminateComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8744:13)
at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9966:16)
at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:13800:12)
It shows the same error for the View Component.
Should it not automatically recognize these components after initial setup?
I have installed the following:
yarn add install -dev react-test-renderer#17.0.1 #testing-library/react-native #testing-library/jest-native
The current Jest configuration in the package.json file:
"jest": {
"preset": "react-native",
"coverageThreshold": {
"app/**/selectors.{js,ts,tsx}": {
"_comment": "Let's strive to increase coverage, instead of lowering it!",
"lines": 57
}
},
"coverageDirectory": ".coverage/",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"native"
],
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js|jsx)$",
"testPathIgnorePatterns": [
"\\.snap$",
"<rootDir>/node_modules/"
],
"cacheDirectory": ".jest/cache",
"setupFiles": [
"./jest.setup.js"
]
}
Seems nothing wrong with the component rendering but the test.
You can use getByText query which can be obtained from render.
Please refer to React Native Testing Library for more information.
import React from 'react';
import {render} from '#testing-library/react-native';
import Greetings from './Greetings';
describe('Greetings component', () => {
it('renders hello world as a test', () => {
const {getByText} = render(<Greetings hello="Hello World!" />);
expect(getByText('Hello World!')).toBeDefined();
});
});
The application was set up a while back and it seems they had mocked out the react-native imports in the jest.setup.js file so that was causing the issue
I am using React, Google Material IO Components to build an app. From a while when I am running JEST for my tests I see this error mentioned below.
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:
C:\Users\sganesh\Documents\gateway-web\packages\payments\node_modules\#material\textfield\helper-text\index.js:23
export * from './component';
^^^^^^
SyntaxError: Unexpected token export
2 | import { useState, useEffect, useRef } from "react";
3 | import { MDCTextField } from "#material/textfield";
> 4 | import { MDCTextFieldHelperText } from "#material/textfield/helper-text";
| ^
5 | import { MDCChipSet } from "#material/chips";
6 | import { MDCFloatingLabel } from "#material/floating-label";
7 | import { MDCTextFieldCharacterCounter } from '#material/textfield/character-counter';
at ScriptTransformer._transformAndBuildScript (node_modules/#jest/transform/build/ScriptTransformer.js:537:17)
at ScriptTransformer.transform (node_modules/#jest/transform/build/ScriptTransformer.js:579:25)
at Object.<anonymous> (src/PaymentContainer/PaymentDetails/common/ChipInput/ChipInput.tsx:4:1)
The Jest Configuration is as follows:-
const base = require('../jest.config.base.js')
// Individual pod can add their add own custom jest config
module.exports = {
...base,
"setupFiles": ['<rootDir>/src/setupTests.ts'],
transformIgnorePatterns: [
"<rootDir>/node_modules/?!(#rmwc|#material)/"
]
};
The Base Jest Config is:
module.exports = {
roots: ["<rootDir>/src"],
transform: {
"^.+\\.(ts|tsx)$": "ts-jest",
".+\\.(css|scss)$": "<rootDir>/node_modules/jest-css-modules-transform"
},
moduleFileExtensions: [
"ts",
"tsx",
"js",
"tsx"
],
"snapshotSerializers": ["enzyme-to-json/serializer"],
verbose: true
};
Try without the <rootDir>
transformIgnorePatterns: [
'node_modules/?!(#rmwc|#material)/'
]
I'm trying to setup a jest snapshot test with redux-persist in my react-native project. I don't think its an es2015 imports problem as my test code looks something like this:
import React from "react"
import "react-native"
// Note: test renderer must be required after react-native.
import renderer from "react-test-renderer"
import App from "../App"
it("renders correctly", () => {
const app = renderer.create(<App />).toJSON()
expect(app).toMatchSnapshot()
})
I ran this exact same test before I added redux-persist and it was working.
Error thrown by jest:
● Test suite failed to run
/Users/a_050313/Documents/dev/scheduling/node_modules/redux-persist/es/integration/react.js:9
import React, { PureComponent } from 'react'; // eslint-disable-line import/no-unresolved
^^^^^^
SyntaxError: Unexpected token import
1 | import React, { Component } from "react"
2 | import { Provider } from "react-redux"
> 3 | import { PersistGate } from "redux-persist/es/integration/react"
4 |
5 | import "./__debug__/ReactotronConfig" // Run Reactron Tools config
6 |
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:318:17)
at Object.<anonymous> (App.js:3:13)
at Object.<anonymous> (__tests__/App.js:7:10)`
The error was related to es2015 imports but It is on jest end. By default jest only transpiles project code and react-native code. So the added libs which aren't already transpilled would error out by jest.
(as mentioned on jest docs)
By default the jest-react-native preset only processes the project's own source files and react-native
Solution provided on the official docs seems a bit hacky but thats the only thing I found:
Add following in your package.json jest: { } section or in jest.config.js file.
"transformIgnorePatterns": [
"node_modules/(?!(react-native|my-project|redux-persist)/)"
]
where the bit redux-persist is the thing that solves the problem. If you have problem with other libs just add their names. My list looks something like this:
"jest": {
"preset": "react-native",
"transformIgnorePatterns": [
"node_modules/(?!(react-native|my-project|redux-persist|react-native-linear-gradient|react-native-vector-icons|react-navigation)/)"
]
}
Additional Note just for redux-persist if you import PersistGate from
import { PersistGate } from "redux-persist/lib/integration/react"
instead
import { PersistGate } from "redux-persist/es/integration/react"
(reference)
you'll get the compiled version but for other libs still you got to this the above mentioned solution.
I have a React storybook and what to use it as my test cases
I have a "loader.js" that import all the stories
import sourceBasic from 'raw-loader!./Basics/foo.js?sourceMap';
import Basic from './Basics/foo';
const tree = {
Basics:[
{
title:'Creating and applying a style',
source:sourceBasic, element:Basic
},
{ .... }
],
[ .... ],
....
}
export default tree
I use the raw-loader and sourceMap to show the source with the element in storybook
This works great.
My problem is when I try to import with Jest
FAIL ./index.test.js
● Test suite failed to run
Cannot find module 'raw-loader!./Basics/foo.js?sourceMap' from 'load.js'
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:179:17)
at Object.<anonymous> (example/stories/load.js:2:34)
The test file
import React from 'react';
import renderer from 'react-test-renderer';
import load from './example/stories/load'
for(const groupName in load ){
const groupArray = load[groupName];
describe(groupName, () => {
for(const item of groupArray ){
test(item.title, () => {
const elem = renderer.create(item.element);
expect(elem.toJSON()).toMatchSnapshot();
}) // END test
} // END for
}) // END describe
} // END for
Thanks for your help
UPDATE
The update and working stroybook as test is implemented on the project react-outline
You can clone it(react-outline), npm install and then npm test to see it in action.
Here is the output on travis :)
If you don't care about the raw-source and want to mock it. You can use the moduleNameMapper under your Jest setting within your package.json.
This will let you intercept all require/import based on a regex match.
Add to your package.json:
...
"dependencies": {
...
},
...
"jest": {
"globals": {
"__TEST__": true
},
"moduleNameMapper": {
"\\.(css|jpg|png)$": "<rootDir>/empty-module.js",
"^raw-loader": "<rootDir>/empty-module.js"
},
"testPathIgnorePatterns": [
"/node_modules/"
],
"verbose": true
}
}
I have a test for Typescript using Jest with Enzyme. Tests work perfect but when i add a component, it gives me a Unterminated regular expression error
import {} from 'jasmine';
import {shallow} from 'enzyme';
import {Show, Hide} from '../components/show_hide';
describe('<Show /> Tests', () => {
it('Show should render once', () => {
const component = shallow(<Show />);
expect(component).toHaveLength(1);
})
})
When I run yarn test the result on the console is
FAIL __tests__/show_hide.ts
● Test suite failed to run
/path/to/repo/__tests__/show_hide.ts: Unterminated regular expression (4:35)
2 | describe('<Show /> Tests', () => {
3 | it('Show should render once', () => {
> 4 | const component = shallow(/>);, expect(component).toHaveLength(1));
| ^
5 | });
6 | });
7 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hvd19oaWRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vX190ZXN0c19fL3Nob3dfaGlkZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sUUFBUSxDQUFDO0FBRy9CLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtJQUMxQixFQUFFLENBQUMsbUJBQW1CLEVBQUU7UUFDdkIsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFPLElBQUksRUFDcEMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQSxDQUFDO0lBQ25DLENBQUMsQ0FBQyxDQUFBO0FBQ0gsQ0FBQyxDQUFDLENBQUEifQ==
The jest configuration inside package.json is
"jest": {
"transform": {
"^.+\\.tsx?$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"json"
],
},
Any thoughts on that?
ts files are for pure typescript code, and tsx for react (like jsx).
Rename the file to tsx
It seems that forgetting to import React caused the issue.